Skip to content

Improve scheduler/oracle test coverage and stabilize CI workflow runtime/toolchain#2

Merged
ServerCrash358 merged 1 commit into
mainfrom
copilot/analyze-test-coverage-and-fix-pipeline
Apr 18, 2026
Merged

Improve scheduler/oracle test coverage and stabilize CI workflow runtime/toolchain#2
ServerCrash358 merged 1 commit into
mainfrom
copilot/analyze-test-coverage-and-fix-pipeline

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 18, 2026

This PR addresses low Go test coverage in core runtime packages and resolves CI instability in the existing pipeline. It adds targeted unit coverage for scheduler/oracle logic and updates workflow runtime/toolchain configuration to match current project and ecosystem requirements.

  • Coverage expansion: scheduler core paths

    • Added focused unit tests for provider lifecycle and invariants:
      • register/get/getActive semantics
      • active-provider counting
      • deregistration behavior
      • reputation clamping bounds
      • HTTP handler validation and response behavior
    • Added scheduler-level tests for:
      • provider eligibility and assignment behavior
      • no-eligible-provider path (pending/unassigned behavior)
      • job retrieval handler behavior
      • metrics output correctness
  • Coverage expansion: scoring and oracle behavior

    • Added scoring tests to validate:
      • weighted scoring behavior
      • oracle-price override impact
      • clamping/normalization expectations
    • Added oracle tests for:
      • set/get/getAll semantics
      • not-found handling in price lookup endpoint
      • pricing feed/jitter expectations
  • Build/CI correctness fixes

    • Implemented missing ProviderManager.GetCount() used by scheduler metrics (removes scheduler package build failure in test job).
    • Updated GitHub Actions workflow to current action/runtime baselines:
      • actions/checkout → v4
      • actions/setup-go → v5 with go-version-file: go.mod
      • actions/setup-node → v4 with Node 22.10.0 (Hardhat-compatible)

Example of the scheduler build fix:

func (pm *ProviderManager) GetCount() int {
	pm.mu.RLock()
	defer pm.mu.RUnlock()

	count := 0
	for _, p := range pm.providers {
		if p.Active {
			count++
		}
	}
	return count
}

@ServerCrash358 ServerCrash358 marked this pull request as ready for review April 18, 2026 18:37
Copilot AI review requested due to automatic review settings April 18, 2026 18:37
@ServerCrash358 ServerCrash358 merged commit d38172b into main Apr 18, 2026
3 checks passed
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR improves reliability and confidence in the scheduler/oracle services by adding targeted Go unit tests and aligning CI tooling/runtime versions with the repo’s current Go/Node requirements.

Changes:

  • Added new unit tests covering scheduler scoring/assignment paths, provider manager semantics/handlers, and oracle handlers/pricing helpers.
  • Implemented ProviderManager.GetCount() to support scheduler metrics and fix a build failure.
  • Updated GitHub Actions workflow to newer actions/* versions and to use Go from go.mod plus a pinned Node version for Hardhat.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
scheduler/scoring_test.go Adds scoring tests for oracle overrides and clamping behavior.
scheduler/scheduler_test.go Adds tests for job submission, handlers, and metrics output.
scheduler/provider_manager_test.go Adds tests for provider lifecycle, handler validation, and JSON responses.
scheduler/provider_manager.go Adds GetCount() for active provider counting (used by metrics).
oracle/pricing_test.go Adds tests for pricing feed contents and jitter bounds.
oracle/oracle_test.go Adds tests for oracle set/get semantics and HTTP endpoints.
.github/workflows/ci.yml Updates action versions and toolchain configuration for Go/Node.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread oracle/oracle_test.go
Comment on lines +68 to +74
var entries []PriceEntry
if err := json.Unmarshal(rec.Body.Bytes(), &entries); err != nil {
t.Fatalf("decode response: %v", err)
}
if len(entries) != 0 {
t.Fatalf("expected empty array, got %d entries", len(entries))
}
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

This test doesn't validate the "array not null" behavior: unmarshalling null into a slice results in nil with len==0, so the test would pass even if the handler encoded null. To assert the response is an empty array, compare the raw body (trimmed) against [], or unmarshal into *[]PriceEntry and ensure the pointer is non-nil.

Copilot uses AI. Check for mistakes.
Comment on lines +83 to +90
s := NewScheduler(pm, "http://127.0.0.1:0", nil)
job, err := s.SubmitJob(JobSubmitRequest{
ClientID: "c1",
CPURequired: 1,
MemoryMB: 512,
MaxDurationSecs: 60,
MaxPricePerHour: 1,
})
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

This test submits a job while the scheduler is configured with oracleURL set to http://127.0.0.1:0. During assignment, fetchOraclePrice will attempt a real HTTP request to that address (connection error -> fallback), introducing unnecessary network dependency/slowness. Consider using an httptest.Server (even one returning 404/empty) for oracleURL so the test stays fully hermetic.

Copilot uses AI. Check for mistakes.
Comment thread scheduler/scoring_test.go
Comment on lines +24 to +26
if results[0].Provider.ID != "p1" {
t.Fatalf("expected p1 to score higher with oracle price override, got %s", results[0].Provider.ID)
}
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

ScoreProviders returns results in the same order as the input slice and does not rank/sort them. This test currently asserts results[0] is p1, which will be true even if p1 scores lower. Sort results by Score before asserting the top provider, or compare the computed scores directly (e.g., results[0].Score > results[1].Score after locating entries by ID).

Suggested change
if results[0].Provider.ID != "p1" {
t.Fatalf("expected p1 to score higher with oracle price override, got %s", results[0].Provider.ID)
}
var p1Result, p2Result *ScoredProvider
for i := range results {
switch results[i].Provider.ID {
case "p1":
p1Result = &results[i]
case "p2":
p2Result = &results[i]
}
}
if p1Result == nil || p2Result == nil {
t.Fatalf("expected results for both p1 and p2")
}
if p1Result.Score <= p2Result.Score {
t.Fatalf("expected p1 to score higher with oracle price override, got p1=%f p2=%f", p1Result.Score, p2Result.Score)
}

Copilot uses AI. Check for mistakes.
Comment on lines +108 to +114
var providers []Provider
if err := json.Unmarshal(rec.Body.Bytes(), &providers); err != nil {
t.Fatalf("decode response: %v", err)
}
if len(providers) != 0 {
t.Fatalf("expected empty provider list, got %d", len(providers))
}
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

This test doesn't actually distinguish between null and [] in the JSON response: unmarshalling null into a slice yields a nil slice with len==0, so the assertion still passes. To verify the handler returns an empty array, inspect the raw response bytes (after trimming whitespace) and assert it equals [], or unmarshal into *[]Provider and assert the pointer is non-nil.

Suggested change
var providers []Provider
if err := json.Unmarshal(rec.Body.Bytes(), &providers); err != nil {
t.Fatalf("decode response: %v", err)
}
if len(providers) != 0 {
t.Fatalf("expected empty provider list, got %d", len(providers))
}
body := strings.TrimSpace(rec.Body.String())
if body != "[]" {
t.Fatalf("expected empty JSON array [], got %q", body)
}

Copilot uses AI. Check for mistakes.
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.

3 participants