Skip to content

feat: CR usage controller - moving CR usage calculation into CRD status, for API usage and Quota usage#800

Open
mblos wants to merge 8 commits intomainfrom
cr-cpu-check
Open

feat: CR usage controller - moving CR usage calculation into CRD status, for API usage and Quota usage#800
mblos wants to merge 8 commits intomainfrom
cr-cpu-check

Conversation

@mblos
Copy link
Copy Markdown
Collaborator

@mblos mblos commented May 5, 2026

Moves CR usage computation out of the API handler and into a dedicated reconciler that persists results in CRD status, making usage data available to both the LIQUID API and quota controller.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

📝 Walkthrough

Walkthrough

Extended CommittedResource status for rollback/retry (AcceptedSpec, ConsecutiveFailures) and per-resource usage (UsedResources, AssignedInstances), added a UsageReconciler controller, Nova images datasource and image model, migrated server table to v3, added generation-aware API polling with exponential backoff, and updated tests/CRD/helm accordingly.

Changes

CommittedResource Controller, Usage, API & Tests

Layer / File(s) Summary
Data Shape / Types
api/v1alpha1/committed_resource_types.go
Added AcceptedSpec *CommittedResourceSpec, ConsecutiveFailures int32, replaced AssignedVMs/UsedAmount with AssignedInstances []string and UsedResources map[string]resource.Quantity.
Config / Defaults
internal/scheduling/reservations/commitments/config.go, helm/bundles/cortex-nova/values.yaml
Added UsageReconcilerConfig with CooldownInterval; added CommittedResourceControllerConfig.MaxRequeueInterval and defaults (includes chart values update).
Core Controller Logic
internal/scheduling/reservations/commitments/committed_resource_controller.go
Exponential backoff via retryDelay, ConsecutiveFailures tracking, isRejectedForGeneration short-circuit, setAccepted snapshots AcceptedSpec, rollbackToAccepted restores from AcceptedSpec, reservation watch suppression past slowdown threshold.
New Reconciliation Controller
internal/scheduling/reservations/commitments/usage_reconciler.go, usage_reconciler_monitor.go
New UsageReconciler controller that builds VM→commitment assignments, writes AssignedInstances and UsedResources into CR status, and exposes Prometheus metrics via UsageReconcilerMonitor.
Usage Calculation & API Wiring
internal/scheduling/reservations/commitments/usage.go, cmd/manager/main.go
CalculateUsage now reads assignments via BuildVMAssignmentsFromStatus; CommitmentStateWithUsage tracks AssignedInstances and UsedVCPUs; manager wires UsageReconciler and monitor.
Indexing & Syncer
internal/scheduling/reservations/commitments/field_index.go, syncer.go
Replaced exported index initializer with unexported index helpers; syncer preserves AllowRejection when applying spec.
API Polling & Rollback
internal/scheduling/reservations/commitments/api/change_commitments.go
crWatch (name+generation) polling to avoid stale conditions; watchCRsUntilReady generation-aware; rollbackCR uses retry.RetryOnConflict.
Tests
internal/scheduling/reservations/commitments/*_test.go, api/change_commitments_test.go
Many new/updated tests: stale-condition regression, rollback behavior (AcceptedSpec), rejected persistence, ConsecutiveFailures/backoff behavior, usage-related test wiring creating CRs and running reconciler to populate status.
CRD / Printing / Visuals
helm/library/cortex/files/crds/cortex.cloud_committedresources.yaml, tools/visualize-committed-resources/main.go
CRD status schema updated (acceptedSpec, consecutiveFailures, assignedInstances, usedResources); print columns changed to UsedMemory and UsedCPU; visualization reads usedResources["memory"]/["cpu"].

Nova Images Datasource, Server v3 Migration & Extractors

Layer / File(s) Summary
API Constant
api/v1alpha1/datasource_types.go
Added NovaDatasourceTypeImages = "images".
Nova API & Glance Client
internal/knowledge/datasources/plugins/openstack/nova/nova_api.go
Added GetAllImages(ctx) ([]Image,error) to NovaAPI; novaAPI holds optional Glance client initialized for images mode; deriveOSType helper added.
Syncer & Model
internal/knowledge/datasources/plugins/openstack/nova/nova_sync.go, nova_types.go
SyncAllImages added and routed from Sync; Image model added (openstack_images table); Server gains ImageRef and JSON marshal/unmarshal handling; Server.TableName() changed to openstack_servers_v3.
DB / Extractors
internal/knowledge/extractor/plugins/compute/*.sql, internal/scheduling/reservations/commitments/usage.go
SQL extractor queries updated to join openstack_servers_v3; VM listing query now joins openstack_images to compute os_type.
Helm / Datasource
helm/bundles/cortex-nova/templates/datasources.yaml
Added nova-images datasource with openstack.nova.type: images and syncInterval: 3600s.
Tests
internal/knowledge/datasources/plugins/openstack/*_test.go
Added mock GetAllImages and TestNovaSyncer_SyncImages; constant test updated to include "images".

Sequence Diagram(s)

sequenceDiagram
    participant API as Change<br/>Commitments API
    participant CR as Committed<br/>Resource CRD
    participant Controller as Committed<br/>Resource Controller
    participant Reconciler as Usage<br/>Reconciler
    participant UsageDB as Usage<br/>DB / Postgres

    API->>CR: Create/Update CommittedResource (with spec)
    CR-->>API: CR created (generation N)
    API->>CR: Poll CR (generation-aware)
    alt CR Ready for generation N
        CR-->>API: Ready=True observed -> API returns success
    else Timeout or Rejected
        API->>CR: Rollback spec -> uses RetryOnConflict to restore AcceptedSpec
    end

    Controller->>CR: Reconcile spec -> try place Reservations
    alt Placement fails and AllowRejection=false
        Controller->>Controller: increment ConsecutiveFailures and RequeueAfter (backoff)
    else Placement succeeds
        Controller->>CR: set AcceptedSpec and reset ConsecutiveFailures
    end

    Reconciler->>UsageDB: Query project VMs (joins images to get os_type)
    Reconciler->>Reconciler: Build VM→commitment assignments
    Reconciler->>CR: Patch Status.AssignedInstances and Status.UsedResources (memory/cpu)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Suggested reviewers

  • auhlig
  • juliusclausnitzer
  • umswmayj
  • SoWieMarkus
  • PhilippMatthes

Poem

🐰
Hopped through specs and Glance-lit skies,
Snapped AcceptedSpec where rollback lies,
Counters back off, retries softly fade,
Assigned instances and CPU/memory laid,
Reconciler hums, and usage finds its way.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: introducing a dedicated CR (CommittedResource) usage controller that moves usage calculation from the API handler into CRD status for broader availability.
Description check ✅ Passed The description accurately summarizes the core change: moving CR usage computation out of the API handler into a dedicated reconciler that persists results in CRD status for use by both LIQUID API and quota controller.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cr-cpu-check

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mblos
Copy link
Copy Markdown
Collaborator Author

mblos commented May 5, 2026

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (5)
internal/knowledge/datasources/plugins/openstack/nova/nova_api.go (2)

89-97: 💤 Low value

Implicit precondition: GetAllImages panics if the datasource type is not Images.

api.glance is only assigned when api.conf.Type == NovaDatasourceTypeImages. Any code path that calls GetAllImages on a non-Images instance will hit a nil-pointer dereference inside glanceimages.List(api.glance, ...). Today the sync router enforces this, but it's an easy regression. Consider either initializing Glance unconditionally (cheap — same provider/availability), or returning a clear error from GetAllImages when api.glance == nil.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/knowledge/datasources/plugins/openstack/nova/nova_api.go` around
lines 89 - 97, GetAllImages can panic because api.glance is only set when
api.conf.Type == v1alpha1.NovaDatasourceTypeImages; add an explicit nil-check at
the start of GetAllImages that returns a clear error (e.g., "glance client not
initialized: datasource type is not Images") if api.glance == nil, and/or
alternatively initialize api.glance unconditionally in the constructor code
shown (the openstack.NewImageV2 call) so api.glance is always non-nil; reference
GetAllImages, api.glance, NovaDatasourceTypeImages, and the glanceimages.List
call when locating where to add the guard or the unconditional initialization.

459-479: ⚡ Quick win

Add request-timer instrumentation for parity with other Get methods.*

Every other Get* method in this file wraps the API call(s) with api.mon.RequestTimer.WithLabelValues(label) for Prometheus tracing. GetAllImages skips it, leaving Glance pagination unmonitored. Adding the same wrapper keeps observability uniform across datasources.

♻️ Proposed change
 func (api *novaAPI) GetAllImages(ctx context.Context) ([]Image, error) {
+	label := Image{}.TableName()
+	slog.Info("fetching nova data", "label", label)
+	if api.mon.RequestTimer != nil {
+		hist := api.mon.RequestTimer.WithLabelValues(label)
+		timer := prometheus.NewTimer(hist)
+		defer timer.ObserveDuration()
+	}
 	var result []Image
 	opts := glanceimages.ListOpts{Limit: 1000}
 	err := glanceimages.List(api.glance, opts).EachPage(ctx, func(_ context.Context, page pagination.Page) (bool, error) {
 		imgs, err := glanceimages.ExtractImages(page)
 		if err != nil {
 			return false, err
 		}
 		for _, img := range imgs {
 			result = append(result, Image{
 				ID:     img.ID,
 				OSType: deriveOSType(img.Properties, img.Tags),
 			})
 		}
 		return true, nil
 	})
 	if err != nil {
 		return nil, fmt.Errorf("failed to list Glance images: %w", err)
 	}
+	slog.Info("fetched", "label", label, "count", len(result))
 	return result, nil
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/knowledge/datasources/plugins/openstack/nova/nova_api.go` around
lines 459 - 479, GetAllImages is missing Prometheus request-timer
instrumentation; wrap the Glance call with the same timer pattern used by other
Get* methods: call
api.mon.RequestTimer.WithLabelValues("glance_images").StartTimer() (or the
existing label naming convention used elsewhere), assign to a timer variable and
defer timer.ObserveDuration(), then run the glanceimages.List(...).EachPage call
as before inside that timed scope; update function novaAPI.GetAllImages to
include this StartTimer/ObserveDuration pairing.
internal/knowledge/datasources/plugins/openstack/nova/nova_types.go (1)

161-168: 💤 Low value

Silent failure when image JSON has unexpected shape.

If the image field is a JSON object but unmarshaling into imageMap fails (e.g., a future Nova response with a non-string id), the error is silently dropped and ImageRef is left empty. That makes such servers indistinguishable from volume-booted servers downstream and harder to diagnose. Consider returning the error (consistent with the flavor/fault handling above) or at least logging it.

♻️ Proposed change
-		if err := json.Unmarshal(aux.Image, &imageMap); err == nil {
-			s.ImageRef = imageMap.ID
-		}
+		if err := json.Unmarshal(aux.Image, &imageMap); err != nil {
+			return err
+		}
+		s.ImageRef = imageMap.ID
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/knowledge/datasources/plugins/openstack/nova/nova_types.go` around
lines 161 - 168, The code currently swallows JSON unmarshal errors for
aux.Image, leaving s.ImageRef empty; instead, when json.Unmarshal(aux.Image,
&imageMap) returns an error you should not drop it—either return the error from
the surrounding UnmarshalJSON (or the equivalent parsing function) or log it
consistently with the earlier flavor/fault handling. Modify the block that
parses aux.Image so that on err != nil you return fmt.Errorf("failed to parse
image JSON: %w", err) (or call the same logger used elsewhere) rather than
ignoring the error, keeping the existing assignment to s.ImageRef when
successful (symbols: aux.Image, imageMap, s.ImageRef).
internal/knowledge/datasources/plugins/openstack/nova/nova_sync_test.go (1)

59-61: ⚡ Quick win

Add a dedicated TestNovaSyncer_SyncImages test to match the pattern of every other sync method.

Every existing sync method has a corresponding named test (TestNovaSyncer_SyncServers, SyncHypervisors, SyncFlavors, etc.), but SyncAllImages has none. The mock is already wired up — the test would be a one-to-one copy of the existing pattern.

✅ Proposed test for `SyncAllImages`
+func TestNovaSyncer_SyncImages(t *testing.T) {
+	dbEnv := testlibDB.SetupDBEnv(t)
+	testDB := db.DB{DbMap: dbEnv.DbMap}
+	defer dbEnv.Close()
+	mon := datasources.Monitor{}
+	syncer := &NovaSyncer{
+		DB:   testDB,
+		Mon:  mon,
+		Conf: v1alpha1.NovaDatasource{Type: v1alpha1.NovaDatasourceTypeImages},
+		API:  &mockNovaAPI{},
+	}
+
+	ctx := t.Context()
+	if err := syncer.Init(ctx); err != nil {
+		t.Fatalf("failed to init nova syncer: %v", err)
+	}
+	n, err := syncer.SyncAllImages(ctx)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	if n != 1 {
+		t.Fatalf("expected 1 image, got %d", n)
+	}
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/knowledge/datasources/plugins/openstack/nova/nova_sync_test.go`
around lines 59 - 61, Add a new unit test named TestNovaSyncer_SyncImages that
mirrors the pattern used by
TestNovaSyncer_SyncServers/SyncHypervisors/SyncFlavors: instantiate the
NovaSyncer with the mockNovaAPI (which implements GetAllImages returning the
sample image), call the sync method (e.g., NovaSyncer.SyncAllImages or the
syncer method that triggers image syncing), and assert that the
returned/side-effect results match the expected image list and no error
occurred; use the same setup/teardown, mock injection, and assertion style as
the other sync tests so it fits the existing test suite conventions.
internal/scheduling/reservations/commitments/usage_reconciler_monitor.go (1)

18-55: ⚡ Quick win

NewUsageReconcilerMonitor returns a value type, but Describe/Collect have pointer receivers — only *UsageReconcilerMonitor satisfies prometheus.Collector.

Any caller that tries to use the returned value directly as a prometheus.Collector (e.g., prometheus.Register(monitor) where monitor := NewUsageReconcilerMonitor()) will get a compile error. The caller is forced to take the address explicitly (&monitor), which is non-obvious given a constructor name.

The idiomatic fix is to return *UsageReconcilerMonitor:

♻️ Proposed fix
-func NewUsageReconcilerMonitor() UsageReconcilerMonitor {
-	m := UsageReconcilerMonitor{
+func NewUsageReconcilerMonitor() *UsageReconcilerMonitor {
+	m := &UsageReconcilerMonitor{
 		reconcileDuration: prometheus.NewHistogramVec(prometheus.HistogramOpts{
 			...
 		}, []string{"result"}),
 		...
 	}

 	// Pre-initialize result labels so metrics appear before the first reconcile.
 	m.reconcileDuration.WithLabelValues("success")
 	m.reconcileDuration.WithLabelValues("error")

 	return m
 }

Please verify how cmd/manager/main.go uses the returned value — if it already passes &monitor to both prometheus.Register and NewUsageReconciler, this is a style concern; if not, it's a compile error waiting to happen.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/scheduling/reservations/commitments/usage_reconciler_monitor.go`
around lines 18 - 55, NewUsageReconcilerMonitor currently returns a value
(UsageReconcilerMonitor) but the methods Describe and Collect have pointer
receivers, so only *UsageReconcilerMonitor implements prometheus.Collector;
change NewUsageReconcilerMonitor to return *UsageReconcilerMonitor and
allocate/return a pointer (e.g., &UsageReconcilerMonitor{...}) so callers can
pass it directly to prometheus.Register and NewUsageReconciler without taking
the address; then verify usages in cmd/manager/main.go (prometheus.Register(...)
and NewUsageReconciler(...)) to ensure they accept the pointer and update any
call sites that expect a value.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmd/manager/main.go`:
- Around line 562-571: The code registers a UsageReconciler even when
commitmentsUsageDB is nil (i.e. no datasource configured), leaving the feature
enabled but non-functional; add a guard before creating/registering
UsageReconciler and its UsageReconcilerMonitor that checks
commitmentsConfig.DatasourceName and commitmentsUsageDB and fail fast (return an
error or log.Fatalf) with a clear message if the datasource is not configured;
specifically, before calling commitments.NewUsageReconcilerMonitor(), verify
commitmentsConfig.DatasourceName != "" and commitmentsUsageDB != nil and only
then create the monitor and call
(&commitments.UsageReconciler{...}).SetupWithManager(mgr, multiclusterClient).

In `@internal/scheduling/reservations/commitments/api/report_usage_test.go`:
- Around line 906-923: The helper toCommittedResourceCRD on UsageTestReservation
drops the commitment StartTime causing ordering-sensitive tests to break; update
toCommittedResourceCRD to copy the reservation's StartTime into the
CommittedResource spec (set Spec.StartTime = tr.StartTime or the appropriate
metav1.Time wrapper used by v1alpha1.CommittedResourceSpec) so synthetic CRDs
preserve the original commitment start time used by the reconciler (reference
UsageTestReservation and toCommittedResourceCRD).

In `@internal/scheduling/reservations/commitments/api/usage_test.go`:
- Around line 335-346: The synthetic CommittedResource created as cr lacks the
reservation time window, so add the reservation's StartTime and EndTime into
cr.Spec to mirror production activation windows; set cr.Spec.StartTime and
cr.Spec.EndTime from the test reservation (e.g.,
r.Spec.CommittedResourceReservation.StartTime and
r.Spec.CommittedResourceReservation.EndTime or r.Spec.StartTime/EndTime as
appropriate) so the reconciler sees the same activation window when exercising
CommittedResource handling.

In
`@internal/scheduling/reservations/commitments/committed_resource_controller.go`:
- Around line 352-363: The legacy fallback currently calls
FromCommittedResource(*cr) which uses the possibly-mutated current spec;
instead, when cr.Status.AcceptedSpec == nil build a temporary CommittedResource
spec that preserves placement/selector/amount from the last-accepted status:
create tempCR := v1alpha1.CommittedResource{Spec: cr.Spec} then overwrite the
placement-related fields (AZ/availability zone, project, domain, flavor/group
and the resource amount) from the corresponding status fields (e.g. use
cr.Status.AcceptedAmount.Value() and the status fields that record accepted
AZ/project/domain/flavor) before calling state, err =
FromCommittedResource(tempCR); keep the existing state.TotalMemoryBytes =
cr.Status.AcceptedAmount.Value() assignment after successful
FromCommittedResource. This ensures FromCommittedResource uses the last-accepted
placement rather than the current mutated CR.
- Around line 471-477: The slowdown gate should only apply to the generation
that actually failed: change the condition in the
committed_resource_controller.go block that currently checks
cr.Status.ConsecutiveFailures >= maxConsecutiveFailuresForSlowdown to also
require the failure is for the current generation (e.g.
cr.Status.FailureGeneration == cr.Generation or
cr.Status.FailedObservedGeneration == cr.ObjectMeta.Generation). Also update the
code that increments/reset ConsecutiveFailures (the failure-recording logic) to
set FailureGeneration = cr.Generation when you increment failures and to reset
ConsecutiveFailures and FailureGeneration when the spec/generation advances (so
new generations start with a fresh count). This ensures suppression only occurs
for the generation that produced the failures.

In `@internal/scheduling/reservations/commitments/usage_reconciler.go`:
- Around line 46-49: Early-return on non-active commitment states (checked via
cr.Spec.State against CommitmentStatusConfirmed and CommitmentStatusGuaranteed)
leaves stale cr.Status.AssignedInstances and cr.Status.UsedResources intact;
instead, when the commitment is not active (i.e., states
planned/pending/superseded/expired), clear/reset cr.Status.AssignedInstances and
cr.Status.UsedResources to empty/zero and persist the change via the status
update path (e.g., r.Status().Update(ctx, cr)) before returning so stale
assignments are not reported as committed usage. Ensure this logic is placed in
the same reconciliation branch that currently returns early after the
cr.Spec.State check.

---

Nitpick comments:
In `@internal/knowledge/datasources/plugins/openstack/nova/nova_api.go`:
- Around line 89-97: GetAllImages can panic because api.glance is only set when
api.conf.Type == v1alpha1.NovaDatasourceTypeImages; add an explicit nil-check at
the start of GetAllImages that returns a clear error (e.g., "glance client not
initialized: datasource type is not Images") if api.glance == nil, and/or
alternatively initialize api.glance unconditionally in the constructor code
shown (the openstack.NewImageV2 call) so api.glance is always non-nil; reference
GetAllImages, api.glance, NovaDatasourceTypeImages, and the glanceimages.List
call when locating where to add the guard or the unconditional initialization.
- Around line 459-479: GetAllImages is missing Prometheus request-timer
instrumentation; wrap the Glance call with the same timer pattern used by other
Get* methods: call
api.mon.RequestTimer.WithLabelValues("glance_images").StartTimer() (or the
existing label naming convention used elsewhere), assign to a timer variable and
defer timer.ObserveDuration(), then run the glanceimages.List(...).EachPage call
as before inside that timed scope; update function novaAPI.GetAllImages to
include this StartTimer/ObserveDuration pairing.

In `@internal/knowledge/datasources/plugins/openstack/nova/nova_sync_test.go`:
- Around line 59-61: Add a new unit test named TestNovaSyncer_SyncImages that
mirrors the pattern used by
TestNovaSyncer_SyncServers/SyncHypervisors/SyncFlavors: instantiate the
NovaSyncer with the mockNovaAPI (which implements GetAllImages returning the
sample image), call the sync method (e.g., NovaSyncer.SyncAllImages or the
syncer method that triggers image syncing), and assert that the
returned/side-effect results match the expected image list and no error
occurred; use the same setup/teardown, mock injection, and assertion style as
the other sync tests so it fits the existing test suite conventions.

In `@internal/knowledge/datasources/plugins/openstack/nova/nova_types.go`:
- Around line 161-168: The code currently swallows JSON unmarshal errors for
aux.Image, leaving s.ImageRef empty; instead, when json.Unmarshal(aux.Image,
&imageMap) returns an error you should not drop it—either return the error from
the surrounding UnmarshalJSON (or the equivalent parsing function) or log it
consistently with the earlier flavor/fault handling. Modify the block that
parses aux.Image so that on err != nil you return fmt.Errorf("failed to parse
image JSON: %w", err) (or call the same logger used elsewhere) rather than
ignoring the error, keeping the existing assignment to s.ImageRef when
successful (symbols: aux.Image, imageMap, s.ImageRef).

In `@internal/scheduling/reservations/commitments/usage_reconciler_monitor.go`:
- Around line 18-55: NewUsageReconcilerMonitor currently returns a value
(UsageReconcilerMonitor) but the methods Describe and Collect have pointer
receivers, so only *UsageReconcilerMonitor implements prometheus.Collector;
change NewUsageReconcilerMonitor to return *UsageReconcilerMonitor and
allocate/return a pointer (e.g., &UsageReconcilerMonitor{...}) so callers can
pass it directly to prometheus.Register and NewUsageReconciler without taking
the address; then verify usages in cmd/manager/main.go (prometheus.Register(...)
and NewUsageReconciler(...)) to ensure they accept the pointer and update any
call sites that expect a value.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: be511876-1fdb-427f-959d-63e23f2e391a

📥 Commits

Reviewing files that changed from the base of the PR and between b4f040a and a8f5aaf.

📒 Files selected for processing (33)
  • api/v1alpha1/committed_resource_types.go
  • api/v1alpha1/datasource_types.go
  • api/v1alpha1/zz_generated.deepcopy.go
  • cmd/manager/main.go
  • helm/bundles/cortex-nova/templates/datasources.yaml
  • helm/bundles/cortex-nova/values.yaml
  • helm/library/cortex/files/crds/cortex.cloud_committedresources.yaml
  • internal/knowledge/datasources/plugins/openstack/controller_test.go
  • internal/knowledge/datasources/plugins/openstack/nova/nova_api.go
  • internal/knowledge/datasources/plugins/openstack/nova/nova_sync.go
  • internal/knowledge/datasources/plugins/openstack/nova/nova_sync_test.go
  • internal/knowledge/datasources/plugins/openstack/nova/nova_types.go
  • internal/knowledge/extractor/plugins/compute/libvirt_domain_cpu_steal_pct.sql
  • internal/knowledge/extractor/plugins/compute/vm_host_residency.sql
  • internal/knowledge/extractor/plugins/compute/vm_life_span.sql
  • internal/knowledge/extractor/plugins/compute/vrops_hostsystem_resolver.sql
  • internal/knowledge/extractor/plugins/compute/vrops_project_noisiness.sql
  • internal/scheduling/reservations/commitments/api/change_commitments.go
  • internal/scheduling/reservations/commitments/api/change_commitments_test.go
  • internal/scheduling/reservations/commitments/api/report_usage_test.go
  • internal/scheduling/reservations/commitments/api/usage_test.go
  • internal/scheduling/reservations/commitments/committed_resource_controller.go
  • internal/scheduling/reservations/commitments/committed_resource_controller_test.go
  • internal/scheduling/reservations/commitments/config.go
  • internal/scheduling/reservations/commitments/field_index.go
  • internal/scheduling/reservations/commitments/reservation_manager.go
  • internal/scheduling/reservations/commitments/reservation_manager_test.go
  • internal/scheduling/reservations/commitments/syncer.go
  • internal/scheduling/reservations/commitments/usage.go
  • internal/scheduling/reservations/commitments/usage_internals_test.go
  • internal/scheduling/reservations/commitments/usage_reconciler.go
  • internal/scheduling/reservations/commitments/usage_reconciler_monitor.go
  • tools/visualize-committed-resources/main.go

Comment thread cmd/manager/main.go Outdated
Comment on lines +562 to +571
usageReconcilerMonitor := commitments.NewUsageReconcilerMonitor()
metrics.Registry.MustRegister(&usageReconcilerMonitor)
usageReconcilerConf := commitmentsConfig.UsageReconciler
usageReconcilerConf.ApplyDefaults()
if err := (&commitments.UsageReconciler{
Client: multiclusterClient,
Conf: usageReconcilerConf,
UsageDB: commitmentsUsageDB,
Monitor: usageReconcilerMonitor,
}).SetupWithManager(mgr, multiclusterClient); err != nil {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fail fast when usage reconciliation has no datasource.

commitmentsUsageDB stays nil when commitmentsConfig.DatasourceName is empty, but this block still registers UsageReconciler with that nil dependency. That leaves the new status-based usage path enabled in a state where it cannot compute any usage data.

Suggested guard
+		if commitmentsUsageDB == nil {
+			setupLog.Error(nil,
+				"committed-resource-reservations-controller requires commitments datasourceName for usage reconciliation")
+			os.Exit(1)
+		}
+
 		usageReconcilerMonitor := commitments.NewUsageReconcilerMonitor()
 		metrics.Registry.MustRegister(&usageReconcilerMonitor)
 		usageReconcilerConf := commitmentsConfig.UsageReconciler
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
usageReconcilerMonitor := commitments.NewUsageReconcilerMonitor()
metrics.Registry.MustRegister(&usageReconcilerMonitor)
usageReconcilerConf := commitmentsConfig.UsageReconciler
usageReconcilerConf.ApplyDefaults()
if err := (&commitments.UsageReconciler{
Client: multiclusterClient,
Conf: usageReconcilerConf,
UsageDB: commitmentsUsageDB,
Monitor: usageReconcilerMonitor,
}).SetupWithManager(mgr, multiclusterClient); err != nil {
if commitmentsUsageDB == nil {
setupLog.Error(nil,
"committed-resource-reservations-controller requires commitments datasourceName for usage reconciliation")
os.Exit(1)
}
usageReconcilerMonitor := commitments.NewUsageReconcilerMonitor()
metrics.Registry.MustRegister(&usageReconcilerMonitor)
usageReconcilerConf := commitmentsConfig.UsageReconciler
usageReconcilerConf.ApplyDefaults()
if err := (&commitments.UsageReconciler{
Client: multiclusterClient,
Conf: usageReconcilerConf,
UsageDB: commitmentsUsageDB,
Monitor: usageReconcilerMonitor,
}).SetupWithManager(mgr, multiclusterClient); err != nil {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/manager/main.go` around lines 562 - 571, The code registers a
UsageReconciler even when commitmentsUsageDB is nil (i.e. no datasource
configured), leaving the feature enabled but non-functional; add a guard before
creating/registering UsageReconciler and its UsageReconcilerMonitor that checks
commitmentsConfig.DatasourceName and commitmentsUsageDB and fail fast (return an
error or log.Fatalf) with a clear message if the datasource is not configured;
specifically, before calling commitments.NewUsageReconcilerMonitor(), verify
commitmentsConfig.DatasourceName != "" and commitmentsUsageDB != nil and only
then create the monitor and call
(&commitments.UsageReconciler{...}).SetupWithManager(mgr, multiclusterClient).

Comment on lines +906 to +923
// toCommittedResourceCRD creates a minimal CommittedResource CRD for this commitment.
// Used by the test setup to pre-populate the CR objects that the usage reconciler writes status into.
func (tr *UsageTestReservation) toCommittedResourceCRD() *v1alpha1.CommittedResource {
amount := resource.MustParse(strconv.FormatInt(tr.Flavor.MemoryMB*int64(tr.Count), 10) + "Mi")
return &v1alpha1.CommittedResource{
ObjectMeta: metav1.ObjectMeta{Name: "cr-" + tr.CommitmentID},
Spec: v1alpha1.CommittedResourceSpec{
CommitmentUUID: tr.CommitmentID,
ProjectID: tr.ProjectID,
DomainID: "test-domain",
AvailabilityZone: tr.AZ,
FlavorGroupName: tr.Flavor.Group,
ResourceType: v1alpha1.CommittedResourceTypeMemory,
State: v1alpha1.CommitmentStatusConfirmed,
Amount: amount,
},
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Preserve StartTime in the synthetic CommittedResource.

The usage path now reads reconciled CommittedResource state, but this helper drops the commitment start time. Tests like “fill oldest commitment first” therefore stop exercising the ordering input they are asserting about.

Suggested fix
 func (tr *UsageTestReservation) toCommittedResourceCRD() *v1alpha1.CommittedResource {
 	amount := resource.MustParse(strconv.FormatInt(tr.Flavor.MemoryMB*int64(tr.Count), 10) + "Mi")
-	return &v1alpha1.CommittedResource{
+	cr := &v1alpha1.CommittedResource{
 		ObjectMeta: metav1.ObjectMeta{Name: "cr-" + tr.CommitmentID},
 		Spec: v1alpha1.CommittedResourceSpec{
 			CommitmentUUID:   tr.CommitmentID,
 			ProjectID:        tr.ProjectID,
 			DomainID:         "test-domain",
 			AvailabilityZone: tr.AZ,
 			FlavorGroupName:  tr.Flavor.Group,
 			ResourceType:     v1alpha1.CommittedResourceTypeMemory,
 			State:            v1alpha1.CommitmentStatusConfirmed,
 			Amount:           amount,
 		},
 	}
+	if !tr.StartTime.IsZero() {
+		cr.Spec.StartTime = &metav1.Time{Time: tr.StartTime}
+	}
+	return cr
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// toCommittedResourceCRD creates a minimal CommittedResource CRD for this commitment.
// Used by the test setup to pre-populate the CR objects that the usage reconciler writes status into.
func (tr *UsageTestReservation) toCommittedResourceCRD() *v1alpha1.CommittedResource {
amount := resource.MustParse(strconv.FormatInt(tr.Flavor.MemoryMB*int64(tr.Count), 10) + "Mi")
return &v1alpha1.CommittedResource{
ObjectMeta: metav1.ObjectMeta{Name: "cr-" + tr.CommitmentID},
Spec: v1alpha1.CommittedResourceSpec{
CommitmentUUID: tr.CommitmentID,
ProjectID: tr.ProjectID,
DomainID: "test-domain",
AvailabilityZone: tr.AZ,
FlavorGroupName: tr.Flavor.Group,
ResourceType: v1alpha1.CommittedResourceTypeMemory,
State: v1alpha1.CommitmentStatusConfirmed,
Amount: amount,
},
}
}
// toCommittedResourceCRD creates a minimal CommittedResource CRD for this commitment.
// Used by the test setup to pre-populate the CR objects that the usage reconciler writes status into.
func (tr *UsageTestReservation) toCommittedResourceCRD() *v1alpha1.CommittedResource {
amount := resource.MustParse(strconv.FormatInt(tr.Flavor.MemoryMB*int64(tr.Count), 10) + "Mi")
cr := &v1alpha1.CommittedResource{
ObjectMeta: metav1.ObjectMeta{Name: "cr-" + tr.CommitmentID},
Spec: v1alpha1.CommittedResourceSpec{
CommitmentUUID: tr.CommitmentID,
ProjectID: tr.ProjectID,
DomainID: "test-domain",
AvailabilityZone: tr.AZ,
FlavorGroupName: tr.Flavor.Group,
ResourceType: v1alpha1.CommittedResourceTypeMemory,
State: v1alpha1.CommitmentStatusConfirmed,
Amount: amount,
},
}
if !tr.StartTime.IsZero() {
cr.Spec.StartTime = &metav1.Time{Time: tr.StartTime}
}
return cr
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/scheduling/reservations/commitments/api/report_usage_test.go` around
lines 906 - 923, The helper toCommittedResourceCRD on UsageTestReservation drops
the commitment StartTime causing ordering-sensitive tests to break; update
toCommittedResourceCRD to copy the reservation's StartTime into the
CommittedResource spec (set Spec.StartTime = tr.StartTime or the appropriate
metav1.Time wrapper used by v1alpha1.CommittedResourceSpec) so synthetic CRDs
preserve the original commitment start time used by the reconciler (reference
UsageTestReservation and toCommittedResourceCRD).

Comment on lines +335 to +346
cr := &v1alpha1.CommittedResource{
ObjectMeta: metav1.ObjectMeta{Name: "cr-" + uuid},
Spec: v1alpha1.CommittedResourceSpec{
CommitmentUUID: uuid,
ProjectID: r.Spec.CommittedResourceReservation.ProjectID,
DomainID: "test-domain",
AvailabilityZone: r.Spec.AvailabilityZone,
FlavorGroupName: r.Spec.CommittedResourceReservation.ResourceGroup,
ResourceType: v1alpha1.CommittedResourceTypeMemory,
State: v1alpha1.CommitmentStatusConfirmed,
Amount: amount,
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Carry the reservation time window into the synthetic CommittedResource.

These cases are asserting expired/future commitment behavior, but the CR reconciled here never gets StartTime or EndTime. With the new status-based flow, that means the test is no longer feeding the reconciler the same activation window data that production uses.

Suggested fix
 				cr := &v1alpha1.CommittedResource{
 					ObjectMeta: metav1.ObjectMeta{Name: "cr-" + uuid},
 					Spec: v1alpha1.CommittedResourceSpec{
 						CommitmentUUID:   uuid,
 						ProjectID:        r.Spec.CommittedResourceReservation.ProjectID,
 						DomainID:         "test-domain",
 						AvailabilityZone: r.Spec.AvailabilityZone,
 						FlavorGroupName:  r.Spec.CommittedResourceReservation.ResourceGroup,
 						ResourceType:     v1alpha1.CommittedResourceTypeMemory,
 						State:            v1alpha1.CommitmentStatusConfirmed,
 						Amount:           amount,
 					},
 				}
+				if r.Spec.StartTime != nil {
+					cr.Spec.StartTime = r.Spec.StartTime.DeepCopy()
+				}
+				if r.Spec.EndTime != nil {
+					cr.Spec.EndTime = r.Spec.EndTime.DeepCopy()
+				}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/scheduling/reservations/commitments/api/usage_test.go` around lines
335 - 346, The synthetic CommittedResource created as cr lacks the reservation
time window, so add the reservation's StartTime and EndTime into cr.Spec to
mirror production activation windows; set cr.Spec.StartTime and cr.Spec.EndTime
from the test reservation (e.g., r.Spec.CommittedResourceReservation.StartTime
and r.Spec.CommittedResourceReservation.EndTime or r.Spec.StartTime/EndTime as
appropriate) so the reconciler sees the same activation window when exercising
CommittedResource handling.

Comment on lines +352 to +363
if cr.Status.AcceptedSpec != nil {
// Use the full accepted spec snapshot: ensures rollback targets the exact previously-accepted
// placement (AZ, amount, project, domain) even if the current spec has been mutated.
tempCR := v1alpha1.CommittedResource{Spec: *cr.Status.AcceptedSpec}
state, err = FromCommittedResource(tempCR)
} else {
// Legacy fallback: AcceptedSpec not yet populated (CR accepted before this field existed).
state, err = FromCommittedResource(*cr)
if err == nil {
state.TotalMemoryBytes = cr.Status.AcceptedAmount.Value()
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

The legacy rollback path restores the new spec, not the last accepted one.

When AcceptedSpec is still nil, this fallback reconstructs state from the current mutated spec and only patches the amount back. For CRs that were already accepted before this field existed, the first failed update after rollout can roll back into the wrong AZ/project/domain/flavor group instead of the previously accepted placement.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@internal/scheduling/reservations/commitments/committed_resource_controller.go`
around lines 352 - 363, The legacy fallback currently calls
FromCommittedResource(*cr) which uses the possibly-mutated current spec;
instead, when cr.Status.AcceptedSpec == nil build a temporary CommittedResource
spec that preserves placement/selector/amount from the last-accepted status:
create tempCR := v1alpha1.CommittedResource{Spec: cr.Spec} then overwrite the
placement-related fields (AZ/availability zone, project, domain, flavor/group
and the resource amount) from the corresponding status fields (e.g. use
cr.Status.AcceptedAmount.Value() and the status fields that record accepted
AZ/project/domain/flavor) before calling state, err =
FromCommittedResource(tempCR); keep the existing state.TotalMemoryBytes =
cr.Status.AcceptedAmount.Value() assignment after successful
FromCommittedResource. This ensures FromCommittedResource uses the last-accepted
placement rather than the current mutated CR.

Comment thread internal/scheduling/reservations/commitments/usage_reconciler.go Outdated
Comment on lines +73 to +80
commitmentsByAZFG, err := calc.buildCommitmentCapacityMap(ctx, logger, cr.Spec.ProjectID)
if err != nil {
r.Monitor.reconcileDuration.WithLabelValues("error").Observe(time.Since(start).Seconds())
return ctrl.Result{}, err
}
if len(commitmentsByAZFG) == 0 {
return ctrl.Result{RequeueAfter: cooldown}, nil
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

cores commitments never enter the status write path.

The reconcile set is derived from Reservation objects, and resourceType=cores explicitly does not create Reservation slots. As a result, CPU commitments never reach writeUsageStatus(), so their status.usedResources stays empty even though this PR moves quota/API usage into CR status.

Also applies to: 108-121

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

Test Coverage Report

Test Coverage 📊: 68.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/monitor.go:21:							NewMonitor					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/monitor.go:39:							Describe					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/monitor.go:45:							Collect						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_api.go:37:			NewCinderAPI					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_api.go:45:			Init						81.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_api.go:68:			GetAllStoragePools				73.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_sync.go:27:			Init						83.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_sync.go:40:			Sync						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_sync.go:51:			SyncAllStoragePools				53.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_types.go:46:			TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_types.go:49:			Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_types.go:52:			UnmarshalJSON					93.9%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/cinder/cinder_types.go:131:			MarshalJSON					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/controller.go:70:				Reconcile					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/controller.go:272:				predicateIgnoreStatusConditions			100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/controller.go:290:				SetupWithManager				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_api.go:35:			NewIdentityAPI					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_api.go:39:			Init						80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_api.go:59:			GetAllDomains					66.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_api.go:83:			GetAllProjects					72.2%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_sync.go:26:			Init						85.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_sync.go:41:			Sync						83.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_sync.go:54:			SyncDomains					53.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_sync.go:74:			SyncProjects					53.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_types.go:16:		TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_types.go:19:		Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_types.go:47:		TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/identity/identity_types.go:50:		Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/limes/limes_api.go:45:			NewLimesAPI					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/limes/limes_api.go:50:			Init						81.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/limes/limes_api.go:74:			GetAllCommitments				90.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/limes/limes_api.go:124:			getCommitments					86.4%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/limes/limes_sync.go:28:			Init						83.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/limes/limes_sync.go:41:			Sync						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/limes/limes_sync.go:52:			SyncCommitments					63.2%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/limes/limes_types.go:69:			TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/limes/limes_types.go:72:			Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_api.go:41:			NewManilaAPI					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_api.go:46:			Init						81.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_api.go:69:			GetAllStoragePools				75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_sync.go:28:			Init						83.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_sync.go:41:			Sync						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_sync.go:52:			SyncAllStoragePools				53.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_types.go:47:			UnmarshalJSON					87.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_types.go:137:			MarshalJSON					72.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_types.go:234:			TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/manila/manila_types.go:237:			Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_api.go:61:				NewNovaAPI					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_api.go:66:				Init						62.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_api.go:102:				GetAllServers					82.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_api.go:170:				GetDeletedServers				82.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_api.go:233:				GetAllHypervisors				82.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_api.go:295:				GetAllFlavors					68.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_api.go:332:				GetAllMigrations				82.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_api.go:393:				GetAllAggregates				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_api.go:459:				GetAllImages					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_api.go:502:				deriveOSType					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_sync.go:29:				Init						91.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_sync.go:55:				Sync						45.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_sync.go:79:				SyncAllServers					57.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_sync.go:102:			SyncDeletedServers				64.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_sync.go:132:			SyncAllHypervisors				57.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_sync.go:156:			SyncAllFlavors					57.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_sync.go:178:			SyncAllMigrations				57.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_sync.go:200:			SyncAllImages					66.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_sync.go:220:			SyncAllAggregates				57.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:36:			UnmarshalJSON					77.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:59:			MarshalJSON					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:79:			TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:82:			Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:138:			UnmarshalJSON					47.6%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:188:			MarshalJSON					84.6%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:234:			TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:237:			Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:270:			UnmarshalJSON					80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:306:			MarshalJSON					85.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:338:			TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:341:			Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:383:			GetHypervisorType				71.4%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:409:			UnmarshalJSON					54.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:432:			MarshalJSON					55.6%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:453:			TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:456:			Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:480:			TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:483:			Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:504:			TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:507:			Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:518:			TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/nova/nova_types.go:521:			Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_api.go:48:		NewPlacementAPI					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_api.go:53:		Init						81.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_api.go:77:		GetAllResourceProviders				66.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_api.go:105:		GetAllTraits					90.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_api.go:155:		getTraits					90.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_api.go:179:		GetAllInventoryUsages				71.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_api.go:229:		getInventoryUsages				77.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_sync.go:28:		Init						87.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_sync.go:46:		Sync						71.4%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_sync.go:62:		SyncResourceProviders				53.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_sync.go:83:		SyncTraits					57.9%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_sync.go:112:		SyncInventoryUsages				57.9%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_types.go:17:		TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_types.go:20:		Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_types.go:31:		TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_types.go:34:		Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_types.go:74:		TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/placement/placement_types.go:77:		Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/openstack/supported_syncers.go:22:			getSupportedSyncer				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/controller.go:57:				Reconcile					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/controller.go:207:				SetupWithManager				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/sync.go:32:					newTypedSyncer					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/sync.go:100:					fetch						79.2%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/sync.go:205:					getSyncWindowStart				81.2%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/sync.go:245:					sync						68.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/sync.go:295:					Sync						70.6%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/triggers.go:7:				TriggerMetricAliasSynced			0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/triggers.go:12:				TriggerMetricTypeSynced				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:42:					TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:43:					Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:44:					GetName						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:45:					GetTimestamp					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:46:					GetValue					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:47:					With						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:90:					TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:91:					Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:92:					GetName						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:93:					GetTimestamp					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:94:					GetValue					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:95:					With						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:145:				TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:146:				Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:147:				GetName						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:148:				GetTimestamp					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:149:				GetValue					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:150:				With						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:170:				TableName					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:171:				Indexes						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:172:				GetName						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:173:				GetTimestamp					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:174:				GetValue					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:175:				With						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:211:				TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:212:				Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:213:				GetName						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:214:				GetTimestamp					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:215:				GetValue					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:216:				With						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:242:				TableName					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:243:				Indexes						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:244:				GetName						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:245:				GetTimestamp					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:246:				GetValue					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:247:				With						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:282:				TableName					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:285:				Indexes						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:286:				GetName						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:287:				GetTimestamp					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:288:				GetValue					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/datasources/plugins/prometheus/types.go:289:				With						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/db.go:51:								FromSecretRef					6.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/db.go:133:								SelectTimed					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/db.go:142:								CreateTable					63.6%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/db.go:161:								AddTable					66.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/db.go:172:								TableExists					58.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/db.go:201:								ReplaceAll					62.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/db.go:230:								BulkInsert					91.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/monitor.go:21:								newMonitor					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/monitor.go:63:								Describe					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/monitor.go:73:								Collect						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/testing/containers/postgres.go:21:					GetPort						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/testing/containers/postgres.go:25:					Init						70.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/testing/containers/postgres.go:69:					Close						50.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/db/testing/env.go:24:							SetupDBEnv					59.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/controller.go:46:							Reconcile					55.2%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/controller.go:238:						SetupWithManager				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/monitor.go:26:							NewMonitor					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/monitor.go:44:							Describe					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/monitor.go:50:							Collect						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/monitor.go:69:							Init						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/monitor.go:78:							monitorFeatureExtractor				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/monitor.go:97:							Extract						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/base.go:28:						Init						87.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/base.go:45:						ExtractSQL					83.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/base.go:58:						Extracted					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/flavor_groups.go:50:				HasFixedRamCoreRatio				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/flavor_groups.go:79:				Extract						82.4%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/host_az.go:31:					Extract						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/host_capabilities.go:35:				Extract						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/host_details.go:59:				Extract						87.2%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/host_pinned_projects.go:45:			Extract						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/host_utilization.go:47:				Extract						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/libvirt_domain_cpu_steal_pct.go:35:		Extract						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/vm_host_residency.go:53:				Extract						85.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/vm_life_span.go:52:				extractHistogramBuckets				89.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/vm_life_span.go:97:				Extract						88.9%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/vrops_hostsystem_contention_long_term.go:39:	Extract						82.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/vrops_hostsystem_contention_short_term.go:39:	Extract						82.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/vrops_hostsystem_resolver.go:33:			Extract						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/compute/vrops_project_noisiness.go:33:			Extract						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/plugins/storage/storage_pool_cpu_usage.go:35:			Extract						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/trigger.go:42:							Reconcile					77.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/trigger.go:95:							findDependentKnowledge				96.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/trigger.go:142:							triggerKnowledgeReconciliation			100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/trigger.go:175:							enqueueKnowledgeReconciliation			81.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/trigger.go:201:							getResourceType					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/trigger.go:213:							mapDatasourceToKnowledge			100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/trigger.go:234:							mapKnowledgeToKnowledge				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/extractor/trigger.go:255:							SetupWithManager				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:53:							Reconcile					42.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:107:							InitAllKPIs					83.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:147:							getJointDB					27.8%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:185:							handleKPIChange					52.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:310:							handleDatasourceChange				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:335:							handleDatasourceCreated				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:345:							handleDatasourceUpdated				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:363:							handleDatasourceDeleted				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:375:							handleKnowledgeChange				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:400:							handleKnowledgeCreated				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:410:							handleKnowledgeUpdated				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:428:							handleKnowledgeDeleted				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/controller.go:438:							SetupWithManager				0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/logger.go:21:								Describe					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/logger.go:26:								Collect						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/logger.go:32:								Init						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/logger.go:37:								GetName						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/base.go:24:							Init						80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/flavor_running_vms.go:37:				GetName						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/flavor_running_vms.go:41:				Init						75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/flavor_running_vms.go:60:				Describe					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/flavor_running_vms.go:64:				Collect						80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/host_contention.go:28:					GetName						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/host_contention.go:32:					Init						80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/host_contention.go:49:					Describe					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/host_contention.go:54:					Collect						82.6%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/host_running_vms.go:42:				GetName						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/host_running_vms.go:46:				Init						75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/host_running_vms.go:69:				Describe					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/host_running_vms.go:73:				Collect						66.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/project_noisiness.go:27:				GetName						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/project_noisiness.go:31:				Init						75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/project_noisiness.go:43:				Describe					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/project_noisiness.go:47:				Collect						75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_kvm.go:29:				getResourceCapacity				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_kvm.go:46:				getResourceAllocation				83.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_kvm.go:58:				getLabels					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_kvm.go:91:				getBuildingBlock				75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_kvm.go:112:				GetName						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_kvm.go:116:				Init						80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_kvm.go:158:				Describe					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_kvm.go:165:				aggregateReservationsByHost			91.9%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_kvm.go:233:				getHypervisors					85.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_kvm.go:246:				Collect						91.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_kvm.go:331:				emitTotal					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/resource_capacity_kvm.go:349:				emitUsage					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_commitments.go:30:					GetName						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_commitments.go:34:					Init						85.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_commitments.go:81:					Describe					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_commitments.go:89:					convertLimesMemory				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_commitments.go:106:					Collect						89.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_faults.go:35:					GetName						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_faults.go:40:					Init						75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_faults.go:53:					Describe					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_faults.go:57:					Collect						91.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_life_span.go:29:					GetName						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_life_span.go:33:					Init						75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_life_span.go:46:					Describe					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_life_span.go:50:					Collect						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_life_span.go:57:					collectVMBuckets				71.4%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_migration_statistics.go:28:				GetName						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_migration_statistics.go:32:				Init						75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_migration_statistics.go:45:				Describe					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/compute/vm_migration_statistics.go:49:				Collect						69.2%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/datasource_state.go:47:				GetName						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/datasource_state.go:52:				Init						80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/datasource_state.go:71:				Describe					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/datasource_state.go:78:				Collect						90.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/decision_state.go:32:				GetName						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/decision_state.go:35:				Init						75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/decision_state.go:49:				Describe					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/decision_state.go:52:				Collect						94.1%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/knowledge_state.go:32:				GetName						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/knowledge_state.go:35:				Init						75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/knowledge_state.go:49:				Describe					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/knowledge_state.go:52:				Collect						85.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/kpi_state.go:32:					GetName						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/kpi_state.go:35:					Init						75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/kpi_state.go:49:					Describe					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/kpi_state.go:52:					Collect						92.9%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/pipeline_state.go:32:				GetName						100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/pipeline_state.go:35:				Init						75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/pipeline_state.go:49:				Describe					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/deployment/pipeline_state.go:52:				Collect						92.9%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/shared.go:28:					getHostLabels					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/shared.go:68:					getMetricName					75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/shared.go:87:					isKVMFlavor					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/shared.go:106:					flavorCPUArchitecture				100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/shared.go:128:					bytesFromUnit					100.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_host_capacity.go:26:			GetName						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_host_capacity.go:30:			Init						80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_host_capacity.go:47:			Describe					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_host_capacity.go:52:			Collect						80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_host_capacity.go:82:			getVMwareHosts					83.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_host_capacity.go:101:			getHostUtilizations				84.6%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_project_utilization.go:51:		GetName						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_project_utilization.go:55:		Init						80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_project_utilization.go:73:		Describe					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_project_utilization.go:78:		Collect						63.2%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_project_utilization.go:136:		getVMwareHosts					83.3%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_project_utilization.go:159:		queryProjectCapacityUsage			80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_project_utilization.go:191:		queryProjectInstanceCount			80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_resource_commitments.go:35:		GetName						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_resource_commitments.go:39:		Init						80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_resource_commitments.go:57:		Describe					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_resource_commitments.go:62:		Collect						62.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_resource_commitments.go:78:		getFlavorsByName				85.7%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_resource_commitments.go:91:		getGeneralPurposeCommitments			75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_resource_commitments.go:106:		getGeneralPurposeServers			87.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_resource_commitments.go:125:		getHanaInstanceCommitments			75.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_resource_commitments.go:139:		getRunningHanaServers				87.5%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_resource_commitments.go:159:		collectGeneralPurpose				74.2%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/infrastructure/vmware_resource_commitments.go:216:		collectHana					88.9%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/storage/storage_pool_cpu.go:28:				GetName						0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/storage/storage_pool_cpu.go:32:				Init						80.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/storage/storage_pool_cpu.go:49:				Describe					0.0%
github.com/cobaltcore-dev/cortex/internal/knowledge/kpis/plugins/storage/storage_pool_cpu.go:54:				Collect						82.6%
github.com/cobaltcore-dev/cortex/internal/knowledge/math/histogram.go:7:							Histogram					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/e2e_checks.go:21:							RunChecks					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/e2e_checks.go:26:							checkCinderSchedulerReturnsValidHosts		0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/external_scheduler_api.go:42:					NewAPI						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/external_scheduler_api.go:50:					Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/external_scheduler_api.go:57:					canRunScheduler					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/external_scheduler_api.go:80:					inferPipelineName				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/external_scheduler_api.go:90:					CinderExternalScheduler				68.8%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/filter_weigher_pipeline_controller.go:48:				PipelineType					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/filter_weigher_pipeline_controller.go:53:				Reconcile					83.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/filter_weigher_pipeline_controller.go:73:				ProcessNewDecisionFromAPI			92.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/filter_weigher_pipeline_controller.go:105:				process						80.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/filter_weigher_pipeline_controller.go:135:				InitPipeline					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/filter_weigher_pipeline_controller.go:148:				SetupWithManager				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/history_cleanup.go:30:						HistoryCleanup					76.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/cinder/pipeline_webhook.go:15:						NewPipelineWebhook				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/external/nova.go:29:							NewNovaReader					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/external/nova.go:34:							GetAllServers					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/external/nova.go:44:							GetAllFlavors					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/external/nova.go:54:							GetAllHypervisors				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/external/nova.go:64:							GetAllMigrations				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/external/nova.go:74:							GetAllAggregates				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/external/nova.go:85:							GetServerByID					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/external/nova.go:99:							GetFlavorByName					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/external/postgres.go:33:							NewPostgresReader				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/external/postgres.go:48:							DB						0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/external/postgres.go:67:							Select						0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/activation.go:12:							NoEffect					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/activation.go:15:							Norm						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/activation.go:21:							Apply						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/api_monitor.go:22:							NewSchedulerMonitor				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/api_monitor.go:32:							Describe					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/api_monitor.go:36:							Collect						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/api_monitor.go:50:							Callback					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/api_monitor.go:56:							Respond						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector.go:53:							Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector.go:64:							Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector.go:75:							CheckKnowledges					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_monitor.go:26:						NewDetectorPipelineMonitor			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_monitor.go:46:						SubPipeline					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_monitor.go:52:						Describe					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_monitor.go:58:						Collect						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_monitor.go:76:						monitorDetector					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_monitor.go:99:						Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_monitor.go:107:						Validate					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_monitor.go:112:						Run						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_pipeline.go:33:						Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_pipeline.go:63:						Run						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_pipeline.go:98:						Combine						97.2%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/detector_step_opts.go:15:						Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter.go:31:								Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_monitor.go:23:							monitorFilter					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_monitor.go:36:							Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_monitor.go:41:							Validate					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_monitor.go:46:							Run						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_validation.go:22:						Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_validation.go:28:						Validate					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_validation.go:33:						validateFilter					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_validation.go:38:						Run						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline.go:45:						InitNewFilterWeigherPipeline			86.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline.go:138:					runFilters					75.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline.go:170:					runWeighers					81.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline.go:210:					normalizeInputWeights				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline.go:219:					applyWeights					80.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline.go:255:					sortHostsByWeights				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline.go:265:					Run						96.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_monitor.go:36:					NewPipelineMonitor				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_monitor.go:90:					SubPipeline					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_monitor.go:97:					observePipelineResult				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_monitor.go:118:				Describe					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_monitor.go:130:				Collect						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_step.go:48:					Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_step.go:63:					Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_step.go:75:					IncludeAllHostsFromRequest			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_step.go:85:					PrepareStats					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_step_monitor.go:42:				monitorStep					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_step_monitor.go:65:				RunWrapped					48.6%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_step_monitor.go:215:				impact						94.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/filter_weigher_pipeline_step_opts.go:15:				Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/history_client.go:32:							joinHostsCapped					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/history_client.go:39:							getName						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/history_client.go:46:							generateExplanation				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/history_client.go:132:							CreateOrUpdateHistory				70.6%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/history_client.go:281:							Delete						80.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_controller.go:38:						InitAllPipelines				93.8%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_controller.go:63:						handlePipelineChange				77.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_controller.go:176:						HandlePipelineCreated				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_controller.go:190:						HandlePipelineUpdated				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_controller.go:203:						HandlePipelineDeleted				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_controller.go:215:						handleKnowledgeChange				71.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_controller.go:248:						HandleKnowledgeCreated				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_controller.go:261:						HandleKnowledgeUpdated				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_controller.go:283:						HandleKnowledgeDeleted				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_webhook.go:38:						ValidateCreate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_webhook.go:47:						ValidateUpdate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_webhook.go:56:						ValidateDelete					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_webhook.go:65:						validatePipeline				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/pipeline_webhook.go:149:						SetupWebhookWithManager				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/scaling.go:7:								clamp						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/scaling.go:22:								MinMaxScale					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher.go:35:								Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher.go:40:								Validate					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher.go:45:								CheckKnowledges					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher_monitor.go:23:							monitorWeigher					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher_monitor.go:36:							Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher_monitor.go:41:							Validate					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher_monitor.go:46:							Run						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher_validation.go:22:						Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher_validation.go:28:						Validate					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher_validation.go:33:						validateWeigher					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/lib/weigher_validation.go:38:						Run						81.8%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/filter_weigher_pipeline_controller.go:52:				PipelineType					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/filter_weigher_pipeline_controller.go:56:				Reconcile					83.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/filter_weigher_pipeline_controller.go:76:				ProcessNewMachine				92.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/filter_weigher_pipeline_controller.go:126:			process						70.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/filter_weigher_pipeline_controller.go:177:			InitPipeline					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/filter_weigher_pipeline_controller.go:190:			handleMachine					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/filter_weigher_pipeline_controller.go:222:			SetupWithManager				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/pipeline_webhook.go:15:						NewPipelineWebhook				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/plugins/filters/filter_noop.go:21:				Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/plugins/filters/filter_noop.go:25:				Validate					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/plugins/filters/filter_noop.go:34:				Run						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/machines/plugins/filters/filter_noop.go:44:				init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/e2e_checks.go:34:							RunChecks					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/e2e_checks.go:39:							checkManilaSchedulerReturnsValidHosts		0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/external_scheduler_api.go:42:					NewAPI						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/external_scheduler_api.go:50:					Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/external_scheduler_api.go:57:					canRunScheduler					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/external_scheduler_api.go:80:					inferPipelineName				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/external_scheduler_api.go:90:					ManilaExternalScheduler				68.8%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/filter_weigher_pipeline_controller.go:48:				PipelineType					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/filter_weigher_pipeline_controller.go:53:				Reconcile					83.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/filter_weigher_pipeline_controller.go:73:				ProcessNewDecisionFromAPI			92.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/filter_weigher_pipeline_controller.go:105:				process						80.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/filter_weigher_pipeline_controller.go:135:				InitPipeline					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/filter_weigher_pipeline_controller.go:148:				SetupWithManager				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/history_cleanup.go:32:						HistoryCleanup					77.6%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/pipeline_webhook.go:15:						NewPipelineWebhook				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/plugins/weighers/netapp_cpu_usage_balancing.go:35:			Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/plugins/weighers/netapp_cpu_usage_balancing.go:53:			Init						60.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/plugins/weighers/netapp_cpu_usage_balancing.go:64:			Run						88.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/manila/plugins/weighers/netapp_cpu_usage_balancing.go:110:			init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/candidate_gatherer.go:29:						MutateWithAllCandidates				94.1%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/deschedulings_cleanup.go:24:						Start						82.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/deschedulings_cleanup.go:63:						Reconcile					70.6%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/deschedulings_cleanup.go:95:						SetupWithManager				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/deschedulings_executor.go:45:						Reconcile					68.2%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/deschedulings_executor.go:256:					SetupWithManager				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/detector_cycle_breaker.go:17:						Filter						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/detector_pipeline_controller.go:42:					PipelineType					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/detector_pipeline_controller.go:47:					InitPipeline					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/detector_pipeline_controller.go:65:					CreateDeschedulingsPeriodically			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/detector_pipeline_controller.go:126:					Reconcile					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/detector_pipeline_controller.go:131:					SetupWithManager				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/e2e_checks.go:61:							getHypervisors					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/e2e_checks.go:104:							prepare						0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/e2e_checks.go:257:							randomRequest					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/e2e_checks.go:330:							checkNovaSchedulerReturnsValidHosts		0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/e2e_checks.go:360:							RunChecks					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/external_scheduler_api.go:54:						NewAPI						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/external_scheduler_api.go:63:						Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/external_scheduler_api.go:70:						canRunScheduler					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/external_scheduler_api.go:93:						inferPipelineName				93.8%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/external_scheduler_api.go:127:					shuffleTopHosts					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/external_scheduler_api.go:153:					limitHostsToRequest				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/external_scheduler_api.go:175:					NovaExternalScheduler				68.5%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/filter_weigher_pipeline_controller.go:51:				PipelineType					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/filter_weigher_pipeline_controller.go:56:				Reconcile					91.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/filter_weigher_pipeline_controller.go:76:				ProcessNewDecisionFromAPI			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/filter_weigher_pipeline_controller.go:106:				upsertHistory					81.8%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/filter_weigher_pipeline_controller.go:127:				process						82.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/filter_weigher_pipeline_controller.go:186:				InitPipeline					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/filter_weigher_pipeline_controller.go:199:				SetupWithManager				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/history_cleanup.go:30:						HistoryCleanup					79.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/hypervisor_overcommit_controller.go:48:				Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/hypervisor_overcommit_controller.go:82:				Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/hypervisor_overcommit_controller.go:111:				Reconcile					93.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/hypervisor_overcommit_controller.go:178:				handleRemoteHypervisor				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/hypervisor_overcommit_controller.go:207:				predicateRemoteHypervisor			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/hypervisor_overcommit_controller.go:220:				SetupWithManager				23.1%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/nova_client.go:80:							NewNovaClient					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/nova_client.go:84:							Init						0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/nova_client.go:132:							Get						75.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/nova_client.go:141:							LiveMigrate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/nova_client.go:152:							GetServerMigrations				70.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/nova_client.go:195:							ListProjectServers				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/pipeline_webhook.go:16:						NewPipelineWebhook				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/detectors/avoid_high_steal_pct.go:26:				Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/detectors/avoid_high_steal_pct.go:39:				Init						80.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/detectors/avoid_high_steal_pct.go:49:				Run						86.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/detectors/avoid_high_steal_pct.go:85:				init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_aggregate_metadata.go:22:			Run						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_aggregate_metadata.go:68:			init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_allowed_projects.go:22:			Run						87.5%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_allowed_projects.go:54:			init						50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_capabilities.go:25:				hvToNovaCapabilities				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_capabilities.go:48:				Run						83.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_capabilities.go:130:				init						50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_correct_az.go:21:				Run						91.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_correct_az.go:65:				init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_exclude_hosts.go:28:				Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_exclude_hosts.go:30:				Run						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_exclude_hosts.go:43:				init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_external_customer.go:23:			Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_external_customer.go:36:			Run						94.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_external_customer.go:86:			init						50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_has_accelerators.go:21:			Run						91.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_has_accelerators.go:55:			init						50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_has_enough_capacity.go:30:			Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_has_enough_capacity.go:60:			Run						81.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_has_enough_capacity.go:364:			init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_has_requested_traits.go:24:			Run						95.5%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_has_requested_traits.go:97:			init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_host_instructions.go:21:			Run						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_host_instructions.go:44:			init						50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_instance_group_affinity.go:19:			Run						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_instance_group_affinity.go:54:			init						50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_instance_group_anti_affinity.go:22:		Run						88.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_instance_group_anti_affinity.go:99:		init						50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_live_migratable.go:22:				checkHasSufficientFeatures			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_live_migratable.go:51:				Run						94.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_live_migratable.go:112:			init						50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_requested_destination.go:26:			processRequestedAggregates			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_requested_destination.go:79:			processRequestedHost				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_requested_destination.go:103:			Run						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_requested_destination.go:128:			init						50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_status_conditions.go:23:			Run						93.1%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/filters/filter_status_conditions.go:88:			init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/vm_detection.go:17:						GetResource					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/vm_detection.go:18:						GetReason					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/vm_detection.go:19:						GetHost						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/vm_detection.go:20:						WithReason					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_binpack.go:29:					Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_binpack.go:72:					Run						90.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_binpack.go:141:					calcVMResources					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_binpack.go:154:					init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_failover_evacuation.go:25:			Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_failover_evacuation.go:29:			GetFailoverHostWeight				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_failover_evacuation.go:36:			GetDefaultHostWeight				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_failover_evacuation.go:53:			Run						93.1%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_failover_evacuation.go:114:			init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_failover_reservation_consolidation.go:29:	Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_failover_reservation_consolidation.go:47:	GetTotalCountWeight				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_failover_reservation_consolidation.go:54:	GetSameSpecPenalty				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_failover_reservation_consolidation.go:81:	Run						94.6%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_failover_reservation_consolidation.go:160:	init						50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_instance_group_soft_affinity.go:29:		Run						94.6%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_instance_group_soft_affinity.go:85:		init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_prefer_smaller_hosts.go:29:			Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_prefer_smaller_hosts.go:60:			Run						92.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/kvm_prefer_smaller_hosts.go:157:			init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_anti_affinity_noisy_projects.go:29:		Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_anti_affinity_noisy_projects.go:44:		Init						80.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_anti_affinity_noisy_projects.go:55:		Run						81.2%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_anti_affinity_noisy_projects.go:93:		init						50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_avoid_long_term_contended_hosts.go:35:	Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_avoid_long_term_contended_hosts.go:53:	Init						80.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_avoid_long_term_contended_hosts.go:64:	Run						88.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_avoid_long_term_contended_hosts.go:111:	init						50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_avoid_short_term_contended_hosts.go:35:	Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_avoid_short_term_contended_hosts.go:53:	Init						80.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_avoid_short_term_contended_hosts.go:64:	Run						88.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_avoid_short_term_contended_hosts.go:111:	init						50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_binpack.go:32:				Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_binpack.go:75:				Init						0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_binpack.go:88:				Run						80.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_binpack.go:165:				calcHostCapacity				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_binpack.go:177:				calcHostAllocation				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_binpack.go:187:				calcVMResources					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/nova/plugins/weighers/vmware_binpack.go:200:				init						50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/filter_weigher_pipeline_controller.go:51:				PipelineType					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/filter_weigher_pipeline_controller.go:55:				Reconcile					83.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/filter_weigher_pipeline_controller.go:75:				ProcessNewPod					92.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/filter_weigher_pipeline_controller.go:126:				process						71.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/filter_weigher_pipeline_controller.go:189:				InitPipeline					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/filter_weigher_pipeline_controller.go:202:				handlePod					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/filter_weigher_pipeline_controller.go:234:				SetupWithManager				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/helpers/resources.go:12:						GetPodResourceRequests				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/helpers/resources.go:31:						AddResourcesInto				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/helpers/resources.go:41:						MaxResourcesInto				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/pipeline_webhook.go:15:						NewPipelineWebhook				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_affinity.go:22:				Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_affinity.go:26:				Validate					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_affinity.go:30:				Run						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_affinity.go:43:				matchesNodeAffinity				88.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_affinity.go:62:				matchesNodeSelectorTerm				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_affinity.go:71:				matchesNodeSelectorRequirement			90.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_affinity.go:124:				init						50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_available.go:21:				Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_available.go:25:				Validate					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_available.go:29:				Run						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_available.go:42:				isNodeHealthy					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_available.go:70:				isNodeSchedulable				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_available.go:74:				init						50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_capacity.go:22:				Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_capacity.go:26:				Validate					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_capacity.go:30:				Run						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_capacity.go:45:				hasCapacityForPod				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_node_capacity.go:60:				init						50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_noop.go:21:					Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_noop.go:25:					Validate					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_noop.go:34:					Run						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_noop.go:44:					init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_taint.go:21:					Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_taint.go:25:					Validate					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_taint.go:29:					Run						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_taint.go:42:					canScheduleOnNode				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_taint.go:53:					hasToleration					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/filters/filter_taint.go:67:					init						50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/weighers/binpack.go:21:					Validate					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/weighers/binpack.go:34:					Run						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/weighers/binpack.go:48:					calculateBinpackScore				85.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/pods/plugins/weighers/binpack.go:83:					init						50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/change_commitments.go:33:			sortedKeys					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/change_commitments.go:66:			HandleChangeCommitments				78.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/change_commitments.go:139:			processCommitmentChanges			85.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/change_commitments.go:343:			watchCRsUntilReady				81.1%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/change_commitments.go:438:			rollbackCR					76.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/change_commitments.go:481:			applyCRSpec					94.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/change_commitments_metrics.go:14:		recordMetrics					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/change_commitments_metrics.go:36:		countCommitments				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/change_commitments_monitor.go:21:		NewChangeCommitmentsAPIMonitor			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/change_commitments_monitor.go:58:		Describe					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/change_commitments_monitor.go:66:		Collect						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/handler.go:33:				NewAPI						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/handler.go:38:				NewAPIWithConfig				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/handler.go:50:				Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/handler.go:67:				handleProjectEndpoint				60.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/info.go:29:					HandleInfo					96.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/info.go:81:					recordInfoMetrics				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/info.go:101:					buildServiceInfo				90.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/info_monitor.go:19:				NewInfoAPIMonitor				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/info_monitor.go:44:				Describe					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/info_monitor.go:50:				Collect						0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/quota.go:19:					HandleQuota					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/report_capacity.go:22:			HandleReportCapacity				72.2%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/report_capacity.go:84:			recordCapacityMetrics				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/report_capacity_monitor.go:19:		NewReportCapacityAPIMonitor			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/report_capacity_monitor.go:44:		Describe					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/report_capacity_monitor.go:50:		Collect						0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/report_usage.go:25:				HandleReportUsage				64.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/report_usage.go:95:				recordUsageMetrics				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/report_usage.go:105:				extractProjectIDFromPath			77.8%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/report_usage_monitor.go:19:			NewReportUsageAPIMonitor			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/report_usage_monitor.go:44:			Describe					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/api/report_usage_monitor.go:50:			Collect						0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/capacity.go:22:					NewCapacityCalculator				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/capacity.go:30:					CalculateCapacity				94.1%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/capacity.go:85:					copyAZCapacity					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/capacity.go:99:					calculateAZCapacity				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/client.go:43:					NewCommitmentsClient				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/client.go:47:					Init						0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/client.go:106:					ListProjects					90.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/client.go:125:					ListCommitmentsByID				79.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/client.go:169:					listCommitments					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/committed_resource_controller.go:44:		Reconcile					81.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/committed_resource_controller.go:91:		reconcilePending				66.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/committed_resource_controller.go:142:		reconcileCommitted				90.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/committed_resource_controller.go:198:		applyReservationState				93.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/committed_resource_controller.go:225:		checkChildReservationStatus			85.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/committed_resource_controller.go:271:		setAccepted					91.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/committed_resource_controller.go:294:		reconcileInactive				75.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/committed_resource_controller.go:302:		reconcileDeletion				71.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/committed_resource_controller.go:316:		deleteChildReservations				75.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/committed_resource_controller.go:338:		rollbackToAccepted				86.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/committed_resource_controller.go:380:		isRejectedForGeneration				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/committed_resource_controller.go:392:		retryDelay					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/committed_resource_controller.go:406:		setNotReady					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/committed_resource_controller.go:412:		setNotReadyRetry				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/committed_resource_controller.go:416:		patchNotReady					85.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/committed_resource_controller.go:436:		SetupWithManager				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/config.go:35:					DefaultUsageReconcilerConfig			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/config.go:42:					ApplyDefaults					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/config.go:82:					DefaultCommittedResourceControllerConfig	0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/config.go:90:					ApplyDefaults					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/config.go:135:					ResourceConfigForGroup				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/config.go:147:					DefaultAPIConfig				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/context.go:20:					WithNewGlobalRequestID				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/context.go:26:					WithGlobalRequestID				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/context.go:33:					LoggerFromContext				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/e2e_checks.go:51:					CheckCommitmentsInfoEndpoint			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/e2e_checks.go:88:					CheckCommitmentsRoundTrip			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/e2e_checks.go:118:				e2eRoundTripResource				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/e2e_checks.go:203:				e2eCheckUsageAPI				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/e2e_checks.go:224:				e2eSendChangeCommitments			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/e2e_checks.go:246:				e2eFetchServiceInfo				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/e2e_checks.go:264:				e2eBaseURL					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/e2e_checks.go:272:				RunCommitmentsE2EChecks				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/field_index.go:21:				indexCommittedResourceByUUID			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/field_index.go:43:				indexReservationByCommitmentUUID		0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/messages.go:135:					UnmarshalJSON					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/messages.go:158:					MarshalJSON					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/reservation_controller.go:48:			echoParentGeneration				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/reservation_controller.go:61:			Reconcile					65.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/reservation_controller.go:355:			reconcileAllocations				80.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/reservation_controller.go:491:			getPipelineForFlavorGroup			66.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/reservation_controller.go:510:			hypervisorToReservations			84.6%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/reservation_controller.go:533:			Init						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/reservation_controller.go:574:			SetupWithManager				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/reservation_manager.go:42:			NewReservationManager				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/reservation_manager.go:63:			ApplyCommitmentState				86.8%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/reservation_manager.go:228:			syncReservationMetadata				82.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/reservation_manager.go:277:			newReservation					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/state.go:33:					ResourceNameRAM					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/state.go:39:					ResourceNameCores				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/state.go:45:					ResourceNameInstances				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/state.go:52:					GetFlavorGroupNameFromResource			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/state.go:110:					FromCommitment					83.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/state.go:159:					FromChangeCommitmentTargetState			90.5%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/state.go:227:					FromCommittedResource				91.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/state.go:258:					FromReservations				95.5%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer.go:47:					NewSyncer					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer.go:55:					Init						75.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer.go:72:					getCommitmentStates				66.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer.go:193:					SyncReservations				59.8%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer.go:385:					applyCommittedResourceSpec			82.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer.go:412:					upsertCommittedResource				90.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer.go:436:					updateCommittedResourceIfExists			83.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer.go:457:					isTerminalCommitment				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer_monitor.go:32:				NewSyncerMonitor				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer_monitor.go:83:				RecordError					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer_monitor.go:87:				RecordDuration					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer_monitor.go:91:				SetLimesCommitmentsActive			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer_monitor.go:95:				RecordStaleCRs					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer_monitor.go:99:				RecordCommitmentSkipped				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer_monitor.go:103:				RecordCRCreates					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer_monitor.go:107:				RecordCRUpdates					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer_monitor.go:111:				RecordCRDeletes					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer_monitor.go:116:				Describe					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/syncer_monitor.go:128:				Collect						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage.go:62:					NewCommitmentStateWithUsage			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage.go:72:					AssignVM					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage.go:83:					HasRemainingCapacity				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage.go:113:					NewUsageCalculator				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage.go:124:					CalculateUsage					85.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage.go:173:					BuildVMAssignmentsFromStatus			80.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage.go:191:					azFlavorGroupKey				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage.go:197:					buildCommitmentCapacityMap			83.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage.go:264:					getProjectVMs					87.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage.go:356:					sortVMsForUsageCalculation			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage.go:375:					sortCommitmentsForAssignment			92.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage.go:403:					assignVMsToCommitments				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage.go:448:					buildUsageResponse				96.4%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage.go:582:					buildVMAttributes				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage.go:610:					countCommitmentStates				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage.go:627:					NewDBUsageClient				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage.go:631:					getReader					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage.go:662:					ListProjectVMs					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage_reconciler.go:37:				Reconcile					69.8%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage_reconciler.go:151:				writeUsageStatus				92.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage_reconciler.go:179:				hypervisorToCommittedResources			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage_reconciler.go:219:				SetupWithManager				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage_reconciler_monitor.go:18:			NewUsageReconcilerMonitor			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage_reconciler_monitor.go:44:			Describe					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/usage_reconciler_monitor.go:51:			Collect						0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/utils.go:13:					GetMaxSlotIndex					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/utils.go:30:					GetNextSlotIndex				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/commitments/utils.go:36:					extractCommitmentUUID				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/context.go:20:						WithGlobalRequestID				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/context.go:26:						WithRequestID					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/context.go:32:						GlobalRequestIDFromContext			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/context.go:43:						RequestIDFromContext				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/config.go:92:					intPtr						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/config.go:97:					ApplyDefaults					87.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/config.go:135:					DefaultConfig					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/context.go:15:					WithNewGlobalRequestID				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/context.go:22:					LoggerFromContext				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/controller.go:50:					NewFailoverReservationController		100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/controller.go:72:					Reconcile					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/controller.go:107:					reconcileValidateAndAcknowledge			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/controller.go:183:					validateReservation				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/controller.go:251:					ReconcilePeriodic				71.2%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/controller.go:384:					reconcileRemoveInvalidVMFromReservations	96.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/controller.go:443:					reconcileRemoveNoneligibleVMFromReservations	93.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/controller.go:503:					reconcileRemoveEmptyReservations		70.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/controller.go:527:					selectVMsToProcess				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/controller.go:571:					sortVMsByMemory					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/controller.go:585:					reconcileCreateAndAssignReservations		78.9%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/controller.go:704:					calculateVMsMissingFailover			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/controller.go:755:					getRequiredFailoverCount			81.8%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/controller.go:777:					patchReservationStatus				50.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/controller.go:811:					SetupWithManager				0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/controller.go:833:					Start						0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/helpers.go:29:					ResourceGroup					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/helpers.go:39:					HypervisorResources				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/helpers.go:49:					resolveVMSpecForScheduling			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/helpers.go:98:					getFailoverAllocations				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/helpers.go:106:					filterFailoverReservations			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/helpers.go:117:					countReservationsForVM				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/helpers.go:130:					addVMToReservation				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/helpers.go:156:					ValidateFailoverReservationResources		0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/helpers.go:177:					newFailoverReservation				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/monitor.go:29:					NewFailoverMonitor				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/monitor.go:88:					preInitialize					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/monitor.go:105:					RecordReconciliation				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/monitor.go:121:					Describe					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/monitor.go:137:					Collect						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/reservation_eligibility.go:39:			IsVMEligibleForReservation			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/reservation_eligibility.go:64:			CheckVMsStillEligible				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/reservation_eligibility.go:105:			FindEligibleReservations			93.8%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/reservation_eligibility.go:139:			reservationKey					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/reservation_eligibility.go:144:			newBaseDependencyGraph				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/reservation_eligibility.go:174:			newDependencyGraph				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/reservation_eligibility.go:190:			ensureVMInMaps					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/reservation_eligibility.go:199:			ensureResInMaps					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/reservation_eligibility.go:206:			addVMToReservation				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/reservation_eligibility.go:216:			removeVMFromReservation				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/reservation_eligibility.go:223:			checkAllVMConstraints				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/reservation_eligibility.go:282:			isVMEligibleForReservation			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/reservation_eligibility.go:292:			doesVMFitInReservation				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/reservation_scheduling.go:33:			queryHypervisorsFromScheduler			82.6%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/reservation_scheduling.go:114:			tryReuseExistingReservation			83.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/reservation_scheduling.go:173:			validateVMViaSchedulerEvacuation		0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/reservation_scheduling.go:254:			scheduleAndBuildNewFailoverReservation		75.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/vm_source.go:58:					NewDBVMSource					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/vm_source.go:63:					ListVMs						78.6%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/vm_source.go:146:					parseExtraSpecs					28.6%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/vm_source.go:161:					truncateString					0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/vm_source.go:170:					GetVM						86.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/vm_source.go:220:					ListVMsOnHypervisors				27.3%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/vm_source.go:264:					buildVMsFromHypervisors				66.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/vm_source.go:333:					filterVMsOnKnownHypervisors			100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/failover/vm_source.go:402:					warnUnknownVMsOnHypervisors			0.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/flavor_groups.go:21:						FindFlavorInGroups				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/flavor_groups.go:39:						Get						85.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/flavor_groups.go:60:						GetAllFlavorGroups				85.7%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/monitor.go:32:						NewMonitor					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/monitor.go:47:						Describe					100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/monitor.go:53:						Collect						100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/scheduler_client.go:25:					loggerFromContext				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/scheduler_client.go:44:					NewSchedulerClient				100.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/scheduler_client.go:92:					ScheduleReservation				73.0%
github.com/cobaltcore-dev/cortex/internal/scheduling/reservations/scheduler_client.go:203:					getSchedulerHints				66.7%
github.com/cobaltcore-dev/cortex/internal/shim/placement/auth.go:72:								compileAuthPolicies				0.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/auth.go:106:								compileRoles					94.7%
github.com/cobaltcore-dev/cortex/internal/shim/placement/auth.go:140:								extractBodyField				94.1%
github.com/cobaltcore-dev/cortex/internal/shim/placement/auth.go:184:								tokenCacheKey					100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/auth.go:189:								get						100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/auth.go:204:								put						100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/auth.go:208:								delete						0.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/auth.go:246:								matchPath					100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/auth.go:256:								matchPolicy					100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/auth.go:265:								authError					100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/auth.go:277:								checkAuth					93.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/auth_keystone.go:20:							initTokenIntrospector				0.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/auth_keystone.go:67:							introspect					84.2%
github.com/cobaltcore-dev/cortex/internal/shim/placement/field_index.go:33:							IndexFields					87.9%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_allocation_candidates.go:35:					HandleListAllocationCandidates			100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_allocations.go:25:						HandleManageAllocations				100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_allocations.go:40:						HandleListAllocations				100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_allocations.go:58:						HandleUpdateAllocations				100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_allocations.go:70:						HandleDeleteAllocations				100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_reshaper.go:25:							HandlePostReshaper				100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_classes.go:33:						HandleListResourceClasses			73.7%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_classes.go:76:						HandleCreateResourceClass			61.3%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_classes.go:129:					handleCreateResourceClassHybrid			0.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_classes.go:169:					HandleShowResourceClass				71.4%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_classes.go:214:					HandleUpdateResourceClass			76.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_classes.go:258:					handleUpdateResourceClassHybrid			81.2%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_classes.go:296:					HandleDeleteResourceClass			78.6%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_classes.go:342:					handleDeleteResourceClassHybrid			81.2%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_classes.go:373:					getResourceClasses				75.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_classes.go:382:					parseResourceClasses				80.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_classes.go:398:					hasResourceClass				80.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_classes.go:408:					writeResourceClassesToConfigMap			81.8%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_classes.go:429:					addResourceClassToConfigMap			56.4%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_classes.go:496:					removeResourceClassFromConfigMap		66.7%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_aggregates.go:48:				HandleListResourceProviderAggregates		87.5%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_aggregates.go:67:				listResourceProviderAggregatesHybrid		100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_aggregates.go:84:				listResourceProviderAggregatesCRD		66.7%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_aggregates.go:109:				writeAggregatesFromCRD				100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_aggregates.go:133:				HandleUpdateResourceProviderAggregates		87.5%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_aggregates.go:152:				updateResourceProviderAggregatesHybrid		23.5%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_aggregates.go:210:				updateResourceProviderAggregatesCRD		71.4%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_allocations.go:18:				HandleListResourceProviderAllocations		100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_inventories.go:19:				HandleListResourceProviderInventories		100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_inventories.go:36:				HandleUpdateResourceProviderInventories		100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_inventories.go:52:				HandleDeleteResourceProviderInventories		100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_inventories.go:66:				HandleShowResourceProviderInventory		80.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_inventories.go:85:				HandleUpdateResourceProviderInventory		80.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_inventories.go:102:				HandleDeleteResourceProviderInventory		80.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_traits.go:42:					HandleListResourceProviderTraits		87.5%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_traits.go:61:					listResourceProviderTraitsHybrid		100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_traits.go:78:					listResourceProviderTraitsCRD			66.7%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_traits.go:103:				writeTraitsFromCRD				100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_traits.go:125:				HandleUpdateResourceProviderTraits		87.5%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_traits.go:144:				updateResourceProviderTraitsHybrid		23.5%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_traits.go:202:				updateResourceProviderTraitsCRD			71.4%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_traits.go:279:				HandleDeleteResourceProviderTraits		87.5%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_traits.go:298:				deleteResourceProviderTraitsHybrid		33.3%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_traits.go:336:				deleteResourceProviderTraitsCRD			53.1%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_provider_usages.go:18:					HandleListResourceProviderUsages		100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_providers.go:54:					translateToResourceProvider			100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_providers.go:114:					HandleCreateResourceProvider			67.3%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_providers.go:209:					HandleShowResourceProvider			64.5%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_providers.go:279:					HandleUpdateResourceProvider			71.7%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_providers.go:375:					HandleDeleteResourceProvider			64.5%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_providers.go:454:					HandleListResourceProviders			60.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_providers.go:468:					listResourceProvidersHybrid			88.7%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_providers.go:560:					listResourceProvidersCRD			0.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_providers.go:589:					applyHypervisorQueryFilters			100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_providers.go:616:					filterHypervisorsByUUID				100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_providers.go:630:					filterHypervisorsByName				100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_providers.go:649:					filterHypervisorsByMemberOf			100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_providers.go:693:					filterHypervisorsByInTree			100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_providers.go:712:					filterHypervisorsByRequired			100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_providers.go:736:					matchesTraitExpr				100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_resource_providers.go:778:					filterHypervisorsByResources			92.9%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_root.go:49:							HandleGetRoot					58.3%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_root.go:90:							staticVersionDocument				100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_root.go:106:							intersectVersions				80.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_root.go:133:							compareVersions					100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_root.go:158:							maxVersion					66.7%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_root.go:165:							minVersion					66.7%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_traits.go:40:							HandleListTraits				83.3%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_traits.go:112:							HandleShowTrait					71.4%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_traits.go:154:							HandleUpdateTrait				68.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_traits.go:198:							handleUpdateTraitHybrid				0.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_traits.go:236:							HandleDeleteTrait				71.4%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_traits.go:282:							handleDeleteTraitHybrid				0.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_traits.go:313:							getTraits					75.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_traits.go:322:							parseTraits					80.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_traits.go:338:							hasTrait					80.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_traits.go:348:							writeTraitsToConfigMap				81.8%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_traits.go:368:							addTraitToConfigMap				56.4%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_traits.go:437:							removeTraitFromConfigMap			66.7%
github.com/cobaltcore-dev/cortex/internal/shim/placement/handle_usages.go:22:							HandleListUsages				100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim.go:85:								orDefault					100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim.go:94:								valid						100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim.go:106:								dispatchPassthroughOnly				80.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim.go:125:								featureModeFromConfOrHeader			100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim.go:232:								validate					91.7%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim.go:342:								Describe					0.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim.go:348:								Collect						0.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim.go:355:								initHTTPClient					60.6%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim.go:411:								initPlacementServiceClient			0.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim.go:450:								Start						0.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim.go:496:								Reconcile					0.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim.go:502:								handleRemoteHypervisor				0.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim.go:510:								predicateRemoteHypervisor			0.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim.go:520:								SetupWithManager				0.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim.go:592:								forward						100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim.go:601:								forwardWithHook					72.3%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim.go:691:								RegisterRoutes					100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim_io.go:24:								Read						100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim_io.go:37:								Write						100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim_io.go:61:								WriteHeader					100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim_io.go:66:								Write						100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim_io.go:86:								writeJSON					55.6%
github.com/cobaltcore-dev/cortex/internal/shim/placement/shim_io.go:103:							wrapHandler					75.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/syncer_resource_classes.go:52:						NewResourceClassSyncer				100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/syncer_resource_classes.go:70:						Init						70.6%
github.com/cobaltcore-dev/cortex/internal/shim/placement/syncer_resource_classes.go:102:					Run						26.7%
github.com/cobaltcore-dev/cortex/internal/shim/placement/syncer_resource_classes.go:134:					sync						64.3%
github.com/cobaltcore-dev/cortex/internal/shim/placement/syncer_traits.go:35:							NewTraitSyncer					100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/syncer_traits.go:53:							Init						70.6%
github.com/cobaltcore-dev/cortex/internal/shim/placement/syncer_traits.go:85:							Run						26.7%
github.com/cobaltcore-dev/cortex/internal/shim/placement/syncer_traits.go:117:							sync						64.3%
github.com/cobaltcore-dev/cortex/internal/shim/placement/validation.go:16:							requiredPathParam				100.0%
github.com/cobaltcore-dev/cortex/internal/shim/placement/validation.go:28:							requiredUUIDPathParam				85.7%
total:																(statements)					68.8%

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
internal/knowledge/datasources/plugins/openstack/nova/nova_sync_test.go (1)

276-306: ⚡ Quick win

Cover the Sync() dispatch for image datasources too.

This test proves SyncAllImages() works, but the controller path goes through NovaSyncer.Sync(). Switching this assertion to syncer.Sync(ctx) would also protect the new NovaDatasourceTypeImages branch while keeping the DB checks below unchanged.

Minimal change
-	n, err := syncer.SyncAllImages(ctx)
+	n, err := syncer.Sync(ctx)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/knowledge/datasources/plugins/openstack/nova/nova_sync_test.go`
around lines 276 - 306, Replace the direct call to SyncAllImages with the
controller dispatch path by invoking NovaSyncer.Sync(ctx) in
TestNovaSyncer_SyncImages so the NovaDatasourceTypeImages branch is exercised;
keep the same assertions (expect no error, expect count n == 1) and the
subsequent DB checks for Image table unchanged, referencing the test function
TestNovaSyncer_SyncImages and the NovaSyncer methods Sync and SyncAllImages and
the NovaDatasource{Type: v1alpha1.NovaDatasourceTypeImages} configuration so the
test still validates the DB contents for img-1 and OSType windows8Server64Guest.
internal/knowledge/datasources/plugins/openstack/nova/nova_api.go (1)

494-523: ⚡ Quick win

Add focused tests for deriveOSType.

This helper now defines the contract for vmware_ostype, ostype: tags, ambiguous-tag fallback, and "unknown", but the provided tests only mock a precomputed OSType. A small table-driven unit test here would lock down the behavior before CR usage depends on it.

Example cases worth pinning down
func TestDeriveOSType(t *testing.T) {
	tests := []struct {
		name       string
		properties map[string]any
		tags       []string
		want       string
	}{
		{
			name:       "vmware_ostype wins",
			properties: map[string]any{"vmware_ostype": "windows8Server64Guest"},
			want:       "windows8Server64Guest",
		},
		{
			name: "single ostype tag",
			tags: []string{"ostype:rhel7_64Guest"},
			want: "rhel7_64Guest",
		},
		{
			name: "multiple ostype tags are ambiguous",
			tags: []string{"ostype:rhel7_64Guest", "ostype:windows8Server64Guest"},
			want: "unknown",
		},
		{
			name: "fallback to unknown",
			want: "unknown",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := deriveOSType(tt.properties, tt.tags); got != tt.want {
				t.Fatalf("deriveOSType() = %q, want %q", got, tt.want)
			}
		})
	}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/knowledge/datasources/plugins/openstack/nova/nova_api.go` around
lines 494 - 523, Add focused table-driven unit tests for deriveOSType to lock
its contract: create TestDeriveOSType that exercises (1) properties with a
non-empty string "vmware_ostype" wins, (2) single "ostype:..." tag returns that
value, (3) multiple "ostype:..." tags produce "unknown" (ambiguous), (4) no info
returns "unknown", and also cover a non-string or empty "vmware_ostype" value
falling back to tags; implement using a tests slice with t.Run and compare
deriveOSType(tt.properties, tt.tags) to the expected want.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@internal/scheduling/reservations/commitments/committed_resource_controller.go`:
- Around line 134-137: The code leaves the
CommittedResource.Status.ConsecutiveFailures count unchanged when
ApplyCommitmentState succeeded but the controller returns early to wait for
child readiness (e.g., the branch that returns ctrl.Result{} with
setNotReady(reason Reserving, "waiting for reservation placement")); update the
reconcile flow so that after a successful ApplyCommitmentState (or any code path
where placement succeeded and we are only passively waiting for child resources)
you reset or clear Status.ConsecutiveFailures (or set a dedicated
lastPlacementFailed boolean) before calling setNotReady or returning without
RequeueAfter; specifically adjust the logic around ApplyCommitmentState, the
setNotReady calls in the Reserving branches and similar branches noted (also the
other branches at the same pattern) to ensure the slowdown gate no longer
observes stale consecutive failure counts.

In `@internal/scheduling/reservations/commitments/usage_reconciler.go`:
- Line 137: The metric usage_reconciler.assignedInstances currently calls
assignedInstances.Set(float64(totalAssigned)) and overwrites values across
projects; update UsageReconcilerMonitor so assignedInstances is either created
with a project_id label and Set is called with that label for each project's
totalAssigned, or change the metric to an aggregate (e.g., maintain a
cluster-wide sum in the reconciler and Set once) depending on intended
semantics—add project_id as a label on the GaugeVec and call
assignedInstances.WithLabelValues(projectID).Set(...) (or implement cluster
aggregation and remove per-project sets); confirm which approach matches
UsageReconcilerMonitor semantics and apply consistently across reconciles.
- Around line 117-131: The statusAge histogram is being observed inside the
inner loop (for _, state := range group) using cr.Status.LastUsageReconcileAt,
causing identical samples to be recorded once per commitment; move the single
observation out of the inner loops so you call r.Monitor.statusAge.Observe(...)
exactly once per reconcile (using
now.Time.Sub(cr.Status.LastUsageReconcileAt.Time).Seconds()) after the loops
complete (or alternatively change to use each
state.Target.Status.LastUsageReconcileAt if you intend per-commitment samples);
update the block around writeUsageStatus/state loop (and variables
written/totalAssigned) so observation happens once per reconcile rather than
inside writeUsageStatus loop.

---

Nitpick comments:
In `@internal/knowledge/datasources/plugins/openstack/nova/nova_api.go`:
- Around line 494-523: Add focused table-driven unit tests for deriveOSType to
lock its contract: create TestDeriveOSType that exercises (1) properties with a
non-empty string "vmware_ostype" wins, (2) single "ostype:..." tag returns that
value, (3) multiple "ostype:..." tags produce "unknown" (ambiguous), (4) no info
returns "unknown", and also cover a non-string or empty "vmware_ostype" value
falling back to tags; implement using a tests slice with t.Run and compare
deriveOSType(tt.properties, tt.tags) to the expected want.

In `@internal/knowledge/datasources/plugins/openstack/nova/nova_sync_test.go`:
- Around line 276-306: Replace the direct call to SyncAllImages with the
controller dispatch path by invoking NovaSyncer.Sync(ctx) in
TestNovaSyncer_SyncImages so the NovaDatasourceTypeImages branch is exercised;
keep the same assertions (expect no error, expect count n == 1) and the
subsequent DB checks for Image table unchanged, referencing the test function
TestNovaSyncer_SyncImages and the NovaSyncer methods Sync and SyncAllImages and
the NovaDatasource{Type: v1alpha1.NovaDatasourceTypeImages} configuration so the
test still validates the DB contents for img-1 and OSType windows8Server64Guest.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4d1aa827-b4c6-4cb0-a435-bb5de63e0a40

📥 Commits

Reviewing files that changed from the base of the PR and between a8f5aaf and 943f2c7.

📒 Files selected for processing (6)
  • cmd/manager/main.go
  • internal/knowledge/datasources/plugins/openstack/nova/nova_api.go
  • internal/knowledge/datasources/plugins/openstack/nova/nova_sync_test.go
  • internal/scheduling/reservations/commitments/committed_resource_controller.go
  • internal/scheduling/reservations/commitments/committed_resource_controller_test.go
  • internal/scheduling/reservations/commitments/usage_reconciler.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmd/manager/main.go

Comment on lines 134 to 137
if !allReady {
// Reservation controller hasn't processed all slots yet; Reservation watch will re-enqueue.
return ctrl.Result{}, r.setNotReady(ctx, cr, v1alpha1.CommittedResourceReasonReserving, "waiting for reservation placement")
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reset the failure counter once apply succeeds and you’re only waiting on child readiness.

After a few AllowRejection=false failures, this path keeps the old ConsecutiveFailures value until final acceptance. If ApplyCommitmentState has already succeeded and the reconcile just returns "waiting for reservation placement", the Reservation watch at Lines 477-481 can still suppress the ready-event requeue for the current generation, while this branch returns no RequeueAfter. That leaves the CR stuck in Reserving even though the child reservations are progressing normally.

Reset the counter before switching into the passive waiting state, or make the slowdown gate depend on an explicit “last reconcile ended in placement failure” marker instead of the raw counter.

Also applies to: 190-193, 271-279, 474-482

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@internal/scheduling/reservations/commitments/committed_resource_controller.go`
around lines 134 - 137, The code leaves the
CommittedResource.Status.ConsecutiveFailures count unchanged when
ApplyCommitmentState succeeded but the controller returns early to wait for
child readiness (e.g., the branch that returns ctrl.Result{} with
setNotReady(reason Reserving, "waiting for reservation placement")); update the
reconcile flow so that after a successful ApplyCommitmentState (or any code path
where placement succeeded and we are only passively waiting for child resources)
you reset or clear Status.ConsecutiveFailures (or set a dedicated
lastPlacementFailed boolean) before calling setNotReady or returning without
RequeueAfter; specifically adjust the logic around ApplyCommitmentState, the
setNotReady calls in the Reserving branches and similar branches noted (also the
other branches at the same pattern) to ensure the slowdown gate no longer
observes stale consecutive failure counts.

Comment on lines +333 to +362
// rollbackToAccepted restores child Reservations to match Status.AcceptedSpec.
// AcceptedSpec is a full snapshot of the spec at the last successful reconcile, so rollback always
// targets the correct AZ, amount, project, domain — even when the current spec has been mutated.
// Falls back to AcceptedAmount + current spec fields for CRs accepted before AcceptedSpec existed.
// If neither is set (CR was never accepted), all child Reservations are deleted.
func (r *CommittedResourceController) rollbackToAccepted(ctx context.Context, logger logr.Logger, cr *v1alpha1.CommittedResource) error {
if cr.Status.AcceptedAmount == nil {
if cr.Status.AcceptedSpec == nil && cr.Status.AcceptedAmount == nil {
return r.deleteChildReservations(ctx, cr)
}
knowledge := &reservations.FlavorGroupKnowledgeClient{Client: r.Client}
flavorGroups, err := knowledge.GetAllFlavorGroups(ctx, nil)
if err != nil {
// Can't compute the rollback target — fall back to full delete rather than leaving
// a partial state that's inconsistent with the unknown AcceptedAmount.
// a partial state that's inconsistent with the unknown accepted state.
logger.Error(err, "flavor knowledge unavailable during rollback, deleting all child reservations")
return r.deleteChildReservations(ctx, cr)
}
state, err := FromCommittedResource(*cr)

var state *CommitmentState
if cr.Status.AcceptedSpec != nil {
// Use the full accepted spec snapshot: ensures rollback targets the exact previously-accepted
// placement (AZ, amount, project, domain) even if the current spec has been mutated.
tempCR := v1alpha1.CommittedResource{Spec: *cr.Status.AcceptedSpec}
state, err = FromCommittedResource(tempCR)
} else {
// AcceptedSpec not yet populated (CR accepted before this field existed).
// We cannot determine the previous placement, so delete all child reservations.
// The controller will recreate them on the next reconcile using the current spec.
logger.Info("AcceptedSpec missing during rollback, deleting child reservations for controller repair")
return r.deleteChildReservations(ctx, cr)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Deleting child reservations here drops migrated accepted CRs with no recovery path.

When AcceptedSpec is still nil, rollbackToAccepted now deletes all child reservations. For already-accepted CRs created before this status field existed, the first rejected update on the current generation empties their active reservations, and isRejectedForGeneration() then prevents the “next reconcile” from re-applying the spec. So this fallback is not just conservative rollback; it can permanently deprovision an accepted commitment until the spec changes again.

Please preserve the last accepted state in this branch instead of deleting it outright, or derive the rollback target from existing accepted state before entering the rejected-generation short-circuit.

Also applies to: 380-385

Comment on lines +117 to +131
for _, group := range commitmentsByAZFG {
for _, state := range group {
if err := r.writeUsageStatus(ctx, state, now); err != nil {
logger.Error(err, "failed to write usage status", "commitmentUUID", state.CommitmentUUID)
writeErr = err
} else {
written++
totalAssigned += len(state.AssignedInstances)
// Observe status age: how long ago was it last reconciled before this run.
if cr.Status.LastUsageReconcileAt != nil {
r.Monitor.statusAge.Observe(now.Time.Sub(cr.Status.LastUsageReconcileAt.Time).Seconds())
}
}
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

statusAge histogram is over-sampled per reconcile.

The Observe call sits inside the inner loop and reads cr.Status.LastUsageReconcileAt from the outer reconciled CR. For a project with N commitments, every reconcile records N identical samples (same delta, same outer timestamp), skewing the histogram toward whichever project has the most commitments. Move the observation outside the loop (one sample per reconcile), or compute the delta from each target.Status.LastUsageReconcileAt if you actually want per-CR status age.

📊 Proposed fix: observe once per reconcile
+	var prevAge *float64
+	if cr.Status.LastUsageReconcileAt != nil {
+		d := now.Time.Sub(cr.Status.LastUsageReconcileAt.Time).Seconds()
+		prevAge = &d
+	}
 	for _, group := range commitmentsByAZFG {
 		for _, state := range group {
 			if err := r.writeUsageStatus(ctx, state, now); err != nil {
 				logger.Error(err, "failed to write usage status", "commitmentUUID", state.CommitmentUUID)
 				writeErr = err
 			} else {
 				written++
 				totalAssigned += len(state.AssignedInstances)
-				// Observe status age: how long ago was it last reconciled before this run.
-				if cr.Status.LastUsageReconcileAt != nil {
-					r.Monitor.statusAge.Observe(now.Time.Sub(cr.Status.LastUsageReconcileAt.Time).Seconds())
-				}
 			}
 		}
 	}
+	if writeErr == nil && prevAge != nil {
+		r.Monitor.statusAge.Observe(*prevAge)
+	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for _, group := range commitmentsByAZFG {
for _, state := range group {
if err := r.writeUsageStatus(ctx, state, now); err != nil {
logger.Error(err, "failed to write usage status", "commitmentUUID", state.CommitmentUUID)
writeErr = err
} else {
written++
totalAssigned += len(state.AssignedInstances)
// Observe status age: how long ago was it last reconciled before this run.
if cr.Status.LastUsageReconcileAt != nil {
r.Monitor.statusAge.Observe(now.Time.Sub(cr.Status.LastUsageReconcileAt.Time).Seconds())
}
}
}
}
var prevAge *float64
if cr.Status.LastUsageReconcileAt != nil {
d := now.Time.Sub(cr.Status.LastUsageReconcileAt.Time).Seconds()
prevAge = &d
}
for _, group := range commitmentsByAZFG {
for _, state := range group {
if err := r.writeUsageStatus(ctx, state, now); err != nil {
logger.Error(err, "failed to write usage status", "commitmentUUID", state.CommitmentUUID)
writeErr = err
} else {
written++
totalAssigned += len(state.AssignedInstances)
}
}
}
if writeErr == nil && prevAge != nil {
r.Monitor.statusAge.Observe(*prevAge)
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/scheduling/reservations/commitments/usage_reconciler.go` around
lines 117 - 131, The statusAge histogram is being observed inside the inner loop
(for _, state := range group) using cr.Status.LastUsageReconcileAt, causing
identical samples to be recorded once per commitment; move the single
observation out of the inner loops so you call r.Monitor.statusAge.Observe(...)
exactly once per reconcile (using
now.Time.Sub(cr.Status.LastUsageReconcileAt.Time).Seconds()) after the loops
complete (or alternatively change to use each
state.Target.Status.LastUsageReconcileAt if you intend per-commitment samples);
update the block around writeUsageStatus/state loop (and variables
written/totalAssigned) so observation happens once per reconcile rather than
inside writeUsageStatus loop.

}

r.Monitor.reconcileDuration.WithLabelValues("success").Observe(time.Since(start).Seconds())
r.Monitor.assignedInstances.Set(float64(totalAssigned))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect the monitor definition to confirm whether assignedInstances has a project label.
fd -t f usage_reconciler_monitor.go --exec cat
rg -nP --type=go -C3 'assignedInstances\b'

Repository: cobaltcore-dev/cortex

Length of output: 7129


assignedInstances.Set() overwrites per-project values across reconciles.

The gauge has no label dimensions and is set to a per-project total at each reconcile run. With multiple projects reconciling sequentially, the metric ends up reflecting only the last reconciled project's value rather than a cluster-wide aggregate as the help text suggests ("across all active commitments").

Add a project_id label to track per-project assignments, or redesign to aggregate across projects (e.g., using a counter with separate reset logic). Confirm the intended semantics with UsageReconcilerMonitor.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/scheduling/reservations/commitments/usage_reconciler.go` at line
137, The metric usage_reconciler.assignedInstances currently calls
assignedInstances.Set(float64(totalAssigned)) and overwrites values across
projects; update UsageReconcilerMonitor so assignedInstances is either created
with a project_id label and Set is called with that label for each project's
totalAssigned, or change the metric to an aggregate (e.g., maintain a
cluster-wide sum in the reconciler and Set once) depending on intended
semantics—add project_id as a label on the GaugeVec and call
assignedInstances.WithLabelValues(projectID).Set(...) (or implement cluster
aggregation and remove per-project sets); confirm which approach matches
UsageReconcilerMonitor semantics and apply consistently across reconciles.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant