printer: read printers and jobs from the spooler API (#2577)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
Jan-Otto Kröpke
2026-10-09 09:36:59 +02:00
committed by GitHub
co-authored by Claude Opus 5.5
parent cb5b4cb0bf
commit 7c200078ef
7 changed files with 774 additions and 138 deletions
+6 -17
View File
@@ -24,7 +24,6 @@ import (
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus-community/windows_exporter/internal/collector/printer"
"github.com/prometheus-community/windows_exporter/internal/mi"
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/assert"
@@ -45,28 +44,18 @@ func TestCollector(t *testing.T) {
testutils.RequireFixtureMetric(t, metrics, printer.Name, "windows_printer_job_count", prometheus.Labels{"printer": "CIPrinter"})
}
// TestCollectorScrapeTimeout checks that the Win32_Printer query is bounded by the scrape timeout.
// Win32_Printer can block for close to a minute on an offline IPP printer; without a timeout,
// that call keeps the collector busy across scrapes.
func TestCollectorScrapeTimeout(t *testing.T) {
miApp, err := mi.ApplicationInitialize()
require.NoError(t, err)
t.Cleanup(func() { assert.NoError(t, miApp.Close()) })
miSession, err := miApp.NewSession(nil)
require.NoError(t, err)
t.Cleanup(func() { assert.NoError(t, miSession.Close()) })
// TestCollectorWithoutMISession checks that the collector does not depend on WMI.
// Win32_Printer can block for close to a minute on an offline IPP printer.
func TestCollectorWithoutMISession(t *testing.T) {
t.Parallel()
c := printer.New(nil)
t.Cleanup(func() { assert.NoError(t, c.Close()) })
require.NoError(t, c.Build(slog.New(slog.DiscardHandler), miSession))
require.NoError(t, c.Build(slog.New(slog.DiscardHandler), nil))
ch := make(chan prometheus.Metric, 1000)
// 1ms is the smallest timeout MI enforces, and well below the time Win32_Printer needs.
err = c.Collect(ch, time.Millisecond)
require.ErrorIs(t, err, mi.MI_RESULT_INVALID_OPERATION_TIMEOUT)
require.ErrorContains(t, err, "failed to collect printer status metrics")
require.NoError(t, c.Collect(ch, time.Second))
}