diff --git a/cmd/exporter/exporter0_test.go b/cmd/exporter/exporter0_test.go
deleted file mode 100644
index 8c04b6b98c..0000000000
--- a/cmd/exporter/exporter0_test.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package your_package_name
-
-import (
- "flag"
- "github.com/onsi/ginkgo/v2"
- . "github.com/onsi/gomega"
-)
-
-var _ = ginkgo.Describe("AppConfig", func() {
- var cfg *AppConfig
-
- ginkgo.BeforeEach(func() {
- // Reset the command-line flags before each test
- flag.CommandLine = flag.NewFlagSet("test", flag.ContinueOnError)
- cfg = newAppConfig()
- })
-
- ginkgo.It("should initialize with default values", func() {
- Expect(cfg.BaseDir).To(Equal(config.BaseDir))
- Expect(cfg.Address).To(Equal("0.0.0.0:8888"))
- Expect(cfg.MetricsPath).To(Equal("/metrics"))
- Expect(cfg.EnableGPU).To(BeFalse())
- Expect(cfg.EnableEBPFCgroupID).To(BeTrue())
- Expect(cfg.ExposeHardwareCounterMetrics).To(BeTrue())
- Expect(cfg.EnableMSR).To(BeFalse())
- Expect(cfg.Kubeconfig).To(BeEmpty())
- Expect(cfg.ApiserverEnabled).To(BeTrue())
- Expect(cfg.RedfishCredFilePath).To(BeEmpty())
- Expect(cfg.ExposeEstimatedIdlePower).To(BeFalse())
- Expect(cfg.MachineSpecFilePath).To(BeEmpty())
- Expect(cfg.DisablePowerMeter).To(BeFalse())
- Expect(cfg.TLSFilePath).To(BeEmpty())
- })
-
- ginkgo.It("should override default values with command-line flags", func() {
- // Set command-line flags
- flag.Set("config-dir", "/custom/config/dir")
- flag.Set("address", "127.0.0.1:8080")
- flag.Set("metrics-path", "/custom/metrics")
- flag.Set("enable-gpu", "true")
- flag.Set("enable-cgroup-id", "false")
- flag.Set("expose-hardware-counter-metrics", "false")
- flag.Set("enable-msr", "true")
- flag.Set("kubeconfig", "/custom/kubeconfig")
- flag.Set("apiserver", "false")
- flag.Set("redfish-cred-file-path", "/custom/redfish/cred")
- flag.Set("expose-estimated-idle-power", "true")
- flag.Set("machine-spec", "/custom/machine/spec")
- flag.Set("disable-power-meter", "true")
- flag.Set("web.config.file", "/custom/tls/config")
-
- // Parse the flags
- flag.Parse()
-
- // Reinitialize the config with the new flag values
- cfg = newAppConfig()
-
- // Verify that the values are overridden
- Expect(cfg.BaseDir).To(Equal("/custom/config/dir"))
- Expect(cfg.Address).To(Equal("127.0.0.1:8080"))
- Expect(cfg.MetricsPath).To(Equal("/custom/metrics"))
- Expect(cfg.EnableGPU).To(BeTrue())
- Expect(cfg.EnableEBPFCgroupID).To(BeFalse())
- Expect(cfg.ExposeHardwareCounterMetrics).To(BeFalse())
- Expect(cfg.EnableMSR).To(BeTrue())
- Expect(cfg.Kubeconfig).To(Equal("/custom/kubeconfig"))
- Expect(cfg.ApiserverEnabled).To(BeFalse())
- Expect(cfg.RedfishCredFilePath).To(Equal("/custom/redfish/cred"))
- Expect(cfg.ExposeEstimatedIdlePower).To(BeTrue())
- Expect(cfg.MachineSpecFilePath).To(Equal("/custom/machine/spec"))
- Expect(cfg.DisablePowerMeter).To(BeTrue())
- Expect(cfg.TLSFilePath).To(Equal("/custom/tls/config"))
- })
-})
\ No newline at end of file
diff --git a/cmd/exporter/exporter1_test.go b/cmd/exporter/exporter1_test.go
deleted file mode 100644
index c3ea102736..0000000000
--- a/cmd/exporter/exporter1_test.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package main
-
-import (
- "net/http"
- "net/http/httptest"
-
- . "github.com/onsi/ginkgo/v2"
- . "github.com/onsi/gomega"
-)
-
-var _ = Describe("HealthProbe", func() {
- var (
- w *httptest.ResponseRecorder
- req *http.Request
- )
-
- BeforeEach(func() {
- // Initialize the response recorder and request before each test
- w = httptest.NewRecorder()
- req = httptest.NewRequest("GET", "/health", nil)
- })
-
- Context("when the health probe is called", func() {
- It("should return HTTP status OK", func() {
- healthProbe(w, req)
-
- Expect(w.Code).To(Equal(http.StatusOK))
- })
-
- It("should return 'ok' in the response body", func() {
- healthProbe(w, req)
-
- Expect(w.Body.String()).To(Equal("ok"))
- })
- })
-})
\ No newline at end of file
diff --git a/cmd/exporter/exporter2_test.go b/cmd/exporter/exporter2_test.go
deleted file mode 100644
index ecd5911846..0000000000
--- a/cmd/exporter/exporter2_test.go
+++ /dev/null
@@ -1,73 +0,0 @@
-package main
-
-import (
- "flag"
- "os"
- "time"
-
- . "github.com/onsi/ginkgo/v2"
- . "github.com/onsi/gomega"
- "k8s.io/klog/v2"
-)
-
-var _ = Describe("Main Function", func() {
- var (
- originalArgs []string
- )
-
- BeforeEach(func() {
- // Save the original command-line arguments
- originalArgs = os.Args
-
- // Reset the flag command-line arguments
- flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
-
- // Initialize klog flags
- klog.InitFlags(nil)
- })
-
- AfterEach(func() {
- // Restore the original command-line arguments
- os.Args = originalArgs
- })
-
- Context("when the config initialization fails", func() {
- It("should log a fatal error and exit", func() {
- // Mock the command-line arguments to simulate a failure scenario
- os.Args = []string{"cmd", "-base-dir=/invalid/path"}
-
- // Redirect klog output to a buffer to capture the log messages
- klog.SetOutput(GinkgoWriter)
-
- // Use a defer to recover from the fatal log and prevent the test from exiting
- defer func() {
- if r := recover(); r != nil {
- Expect(r).To(ContainSubstring("Failed to initialize config"))
- }
- }()
-
- // Call the main function
- main()
- })
- })
-
- Context("when the config initialization succeeds", func() {
- It("should initialize the config without errors", func() {
- // Mock the command-line arguments to simulate a success scenario
- os.Args = []string{"cmd", "-base-dir=/valid/path"}
-
- // Redirect klog output to a buffer to capture the log messages
- klog.SetOutput(GinkgoWriter)
-
- // Use a defer to recover from the fatal log and prevent the test from exiting
- defer func() {
- if r := recover(); r != nil {
- Fail("Unexpected fatal log")
- }
- }()
-
- // Call the main function
- main()
- })
- })
-})
\ No newline at end of file
diff --git a/cmd/exporter/exporter3_test.go b/cmd/exporter/exporter3_test.go
deleted file mode 100644
index bb10125cd1..0000000000
--- a/cmd/exporter/exporter3_test.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package main
-
-import (
- "net/http"
- "net/http/httptest"
- "strings"
-
- . "github.com/onsi/ginkgo/v2"
- . "github.com/onsi/gomega"
-)
-
-var _ = Describe("RootHandler", func() {
- var (
- metricPathConfig string
- handler http.HandlerFunc
- recorder *httptest.ResponseRecorder
- request *http.Request
- )
-
- BeforeEach(func() {
- metricPathConfig = "/metrics"
- handler = rootHandler(metricPathConfig)
- recorder = httptest.NewRecorder()
- request = httptest.NewRequest("GET", "/", nil)
- })
-
- Context("when the root endpoint is accessed", func() {
- It("should return a valid HTML response with the correct metric path", func() {
- handler.ServeHTTP(recorder, request)
-
- Expect(recorder.Code).To(Equal(http.StatusOK))
- Expect(recorder.Body.String()).To(ContainSubstring("
Energy Stats Exporter"))
- Expect(recorder.Body.String()).To(ContainSubstring("Energy Stats Exporter
"))
- Expect(recorder.Body.String()).To(ContainSubstring(`Metrics`))
- })
- })
-
- Context("when the response writing fails", func() {
- It("should log an error", func() {
- // Mock the response writer to simulate a write failure
- failingRecorder := &FailingResponseRecorder{httptest.NewRecorder()}
- handler.ServeHTTP(failingRecorder, request)
-
- // Here you would typically check if the error was logged.
- // Since klog is used, you might need to capture logs or mock klog for this test.
- // This is a placeholder to indicate where you would check for the error log.
- Expect(failingRecorder.Failed).To(BeTrue())
- })
- })
-})
-
-// FailingResponseRecorder is a custom ResponseRecorder that fails on Write
-type FailingResponseRecorder struct {
- *httptest.ResponseRecorder
- Failed bool
-}
-
-func (r *FailingResponseRecorder) Write(b []byte) (int, error) {
- if strings.Contains(string(b), "Metrics") {
- r.Failed = true
- return 0, fmt.Errorf("simulated write failure")
- }
- return r.ResponseRecorder.Write(b)
-}
\ No newline at end of file
diff --git a/cmd/exporter/exporter_suite_test.go b/cmd/exporter/exporter_suite_test.go
new file mode 100644
index 0000000000..6b8b879998
--- /dev/null
+++ b/cmd/exporter/exporter_suite_test.go
@@ -0,0 +1,13 @@
+package main
+
+import (
+ "testing"
+
+ . "github.com/onsi/ginkgo/v2"
+ . "github.com/onsi/gomega"
+)
+
+func TestExporter(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Exporter Suite")
+}
diff --git a/cmd/exporter/exporter_test.go b/cmd/exporter/exporter_test.go
new file mode 100644
index 0000000000..7bf65425b3
--- /dev/null
+++ b/cmd/exporter/exporter_test.go
@@ -0,0 +1,159 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "net/http"
+ "net/http/httptest"
+ "strings"
+
+ . "github.com/onsi/ginkgo/v2"
+ . "github.com/onsi/gomega"
+ "github.com/sustainable-computing-io/kepler/pkg/config"
+)
+
+var _ = Describe("AppConfig", func() {
+ var cfg *AppConfig
+
+ BeforeEach(func() {
+ cfg = newAppConfig()
+ // Reset the command-line flags before each test
+ flag.CommandLine = flag.NewFlagSet("test", flag.ContinueOnError)
+ })
+
+ It("should initialize with default values", func() {
+ Expect(cfg.BaseDir).To(Equal(config.BaseDir))
+ Expect(cfg.Address).To(Equal("0.0.0.0:8888"))
+ Expect(cfg.MetricsPath).To(Equal("/metrics"))
+ Expect(cfg.EnableGPU).To(BeFalse())
+ Expect(cfg.EnableEBPFCgroupID).To(BeTrue())
+ Expect(cfg.ExposeHardwareCounterMetrics).To(BeTrue())
+ Expect(cfg.EnableMSR).To(BeFalse())
+ Expect(cfg.Kubeconfig).To(BeEmpty())
+ Expect(cfg.ApiserverEnabled).To(BeTrue())
+ Expect(cfg.RedfishCredFilePath).To(BeEmpty())
+ Expect(cfg.ExposeEstimatedIdlePower).To(BeFalse())
+ Expect(cfg.MachineSpecFilePath).To(BeEmpty())
+ Expect(cfg.DisablePowerMeter).To(BeFalse())
+ Expect(cfg.TLSFilePath).To(BeEmpty())
+ })
+
+ It("should override default values with command-line flags", func() {
+ cfg = newAppConfig()
+ // Set command-line flags
+ flag.Set("config-dir", "/custom/config/dir")
+ flag.Set("address", "127.0.0.1:8080")
+ flag.Set("metrics-path", "/custom/metrics")
+ flag.Set("enable-gpu", "true")
+ flag.Set("enable-cgroup-id", "false")
+ flag.Set("expose-hardware-counter-metrics", "false")
+ flag.Set("enable-msr", "true")
+ flag.Set("kubeconfig", "/custom/kubeconfig")
+ flag.Set("apiserver", "false")
+ flag.Set("redfish-cred-file-path", "/custom/redfish/cred")
+ flag.Set("expose-estimated-idle-power", "true")
+ flag.Set("machine-spec", "/custom/machine/spec")
+ flag.Set("disable-power-meter", "true")
+ flag.Set("web.config.file", "/custom/tls/config")
+
+ // Parse the flags
+ flag.Parse()
+
+ // Verify that the values are overridden
+ Expect(cfg.BaseDir).To(Equal("/custom/config/dir"))
+ Expect(cfg.Address).To(Equal("127.0.0.1:8080"))
+ Expect(cfg.MetricsPath).To(Equal("/custom/metrics"))
+ Expect(cfg.EnableGPU).To(BeTrue())
+ Expect(cfg.EnableEBPFCgroupID).To(BeFalse())
+ Expect(cfg.ExposeHardwareCounterMetrics).To(BeFalse())
+ Expect(cfg.EnableMSR).To(BeTrue())
+ Expect(cfg.Kubeconfig).To(Equal("/custom/kubeconfig"))
+ Expect(cfg.ApiserverEnabled).To(BeFalse())
+ Expect(cfg.RedfishCredFilePath).To(Equal("/custom/redfish/cred"))
+ Expect(cfg.ExposeEstimatedIdlePower).To(BeTrue())
+ Expect(cfg.MachineSpecFilePath).To(Equal("/custom/machine/spec"))
+ Expect(cfg.DisablePowerMeter).To(BeTrue())
+ Expect(cfg.TLSFilePath).To(Equal("/custom/tls/config"))
+ })
+})
+
+var _ = Describe("HealthProbe", func() {
+ var (
+ w *httptest.ResponseRecorder
+ req *http.Request
+ )
+
+ BeforeEach(func() {
+ // Initialize the response recorder and request before each test
+ w = httptest.NewRecorder()
+ req = httptest.NewRequest("GET", "/health", nil)
+ })
+
+ Context("when the health probe is called", func() {
+ It("should return HTTP status OK", func() {
+ healthProbe(w, req)
+
+ Expect(w.Code).To(Equal(http.StatusOK))
+ })
+
+ It("should return 'ok' in the response body", func() {
+ healthProbe(w, req)
+
+ Expect(w.Body.String()).To(Equal("ok"))
+ })
+ })
+})
+
+var _ = Describe("RootHandler", func() {
+ var (
+ metricPathConfig string
+ handler http.HandlerFunc
+ recorder *httptest.ResponseRecorder
+ request *http.Request
+ )
+
+ BeforeEach(func() {
+ metricPathConfig = "/metrics"
+ handler = rootHandler(metricPathConfig)
+ recorder = httptest.NewRecorder()
+ request = httptest.NewRequest("GET", "/", nil)
+ })
+
+ Context("when the root endpoint is accessed", func() {
+ It("should return a valid HTML response with the correct metric path", func() {
+ handler.ServeHTTP(recorder, request)
+
+ Expect(recorder.Code).To(Equal(http.StatusOK))
+ Expect(recorder.Body.String()).To(ContainSubstring("Energy Stats Exporter"))
+ Expect(recorder.Body.String()).To(ContainSubstring("Energy Stats Exporter
"))
+ Expect(recorder.Body.String()).To(ContainSubstring(`Metrics`))
+ })
+ })
+
+ Context("when the response writing fails", func() {
+ It("should log an error", func() {
+ // Mock the response writer to simulate a write failure
+ failingRecorder := &FailingResponseRecorder{httptest.NewRecorder(), false}
+ handler.ServeHTTP(failingRecorder, request)
+
+ // Here you would typically check if the error was logged.
+ // Since klog is used, you might need to capture logs or mock klog for this test.
+ // This is a placeholder to indicate where you would check for the error log.
+ Expect(failingRecorder.Failed).To(BeTrue())
+ })
+ })
+})
+
+// FailingResponseRecorder is a custom ResponseRecorder that fails on Write
+type FailingResponseRecorder struct {
+ *httptest.ResponseRecorder
+ Failed bool
+}
+
+func (r *FailingResponseRecorder) Write(b []byte) (int, error) {
+ if strings.Contains(string(b), "Metrics") {
+ r.Failed = true
+ return 0, fmt.Errorf("simulated write failure")
+ }
+ return r.ResponseRecorder.Write(b)
+}
diff --git a/pkg/collector/metric_collector_test.go b/pkg/collector/metric_collector_test.go
index 00c069ff80..01aeaadf0e 100644
--- a/pkg/collector/metric_collector_test.go
+++ b/pkg/collector/metric_collector_test.go
@@ -1,6 +1,8 @@
package collector
import (
+ "testing"
+
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
@@ -74,3 +76,23 @@ var _ = Describe("Test Collector Unit", func() {
})
})
+
+func BenchmarkHandleInactiveContainers(b *testing.B) {
+ // Initialize the mock exporter and collector
+ config.Initialize(".")
+ bpfExporter := bpf.NewMockExporter(bpf.DefaultSupportedMetrics())
+ metricCollector := newMockCollector(bpfExporter)
+
+ // Create a map of found containers
+ foundContainer := make(map[string]bool)
+ foundContainer["container1"] = true
+ foundContainer["container2"] = true
+
+ // Reset the timer to exclude setup time from the benchmark
+ b.ResetTimer()
+
+ // Run the benchmark
+ for i := 0; i < b.N; i++ {
+ metricCollector.handleInactiveContainers(foundContainer)
+ }
+}