From 68b84d2ad3a9ce46126ee9f99439d78506be4ce0 Mon Sep 17 00:00:00 2001 From: armirveliaj Date: Tue, 17 Sep 2024 10:43:48 -0400 Subject: [PATCH] Add new unit tests on cores --- cores/core_test.go | 51 +++++++++++++++ cores/metrics_test.go | 144 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 cores/metrics_test.go diff --git a/cores/core_test.go b/cores/core_test.go index 21e323b16..a60e3fe16 100644 --- a/cores/core_test.go +++ b/cores/core_test.go @@ -20,7 +20,10 @@ package cores import ( "errors" + "fmt" + "os" "reflect" + "strings" "sync" "testing" "time" @@ -172,3 +175,51 @@ func TestV1StopCPUProfiling(t *testing.T) { }) } } + +func TestWriteHeapProfile(t *testing.T) { + tmpFilePath := "test_heap_profile.pprof" + defer os.Remove(tmpFilePath) + t.Run("Success", func(t *testing.T) { + err := writeHeapProfile(tmpFilePath) + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + if _, err := os.Stat(tmpFilePath); os.IsNotExist(err) { + t.Fatal("expected file to be created") + } + }) + + t.Run("FileCreationError", func(t *testing.T) { + invalidPath := "/invalid/path/to/file.pprof" + err := writeHeapProfile(invalidPath) + if err == nil { + t.Fatal("expected an error but got none") + } + if !strings.Contains(err.Error(), "could not create memory profile") { + t.Fatalf("unexpected error message: %v", err) + } + }) +} + +func TestNewMemProfNameFunc(t *testing.T) { + t.Run("NoTimestamp", func(t *testing.T) { + gen := newMemProfNameFunc(0, false) + for i := 1; i <= 3; i++ { + expected := fmt.Sprintf("mem_%d.prof", i) + result := gen() + if result != expected { + t.Errorf("expected %s, got %s", expected, result) + } + } + }) + + t.Run("Timestamp1SecondOrMore", func(t *testing.T) { + gen := newMemProfNameFunc(1*time.Second, true) + now := time.Now() + result := gen() + expected := fmt.Sprintf("mem_%s.prof", now.Format("20060102150405")) + if result != expected { + t.Errorf("expected %s, got %s", expected, result) + } + }) +} diff --git a/cores/metrics_test.go b/cores/metrics_test.go new file mode 100644 index 000000000..1d970e162 --- /dev/null +++ b/cores/metrics_test.go @@ -0,0 +1,144 @@ +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package cores + +import ( + "os" + "reflect" + "runtime" + "testing" + + "github.com/prometheus/procfs" +) + +func TestStatusMetricsToMap(t *testing.T) { + memStats := GoMemStats{ + Alloc: 20, + TotalAlloc: 100, + Sys: 1, + Mallocs: 1, + Frees: 1, + Lookups: 2012, + HeapAlloc: 1000, + HeapSys: 10, + HeapIdle: 500, + HeapInuse: 10, + HeapReleased: 300, + HeapObjects: 10, + StackInuse: 300, + StackSys: 10, + MSpanSys: 200, + MSpanInuse: 1, + MCacheInuse: 30, + MCacheSys: 300, + BuckHashSys: 20, + GCSys: 30, + OtherSys: 30, + NextGC: 40, + LastGC: 40.4, + } + gcDurationStats := GCDurationStats{} + procStats := ProcStats{} + capsStats := &CapsStats{} + + sm := StatusMetrics{ + PID: 1234, + GoVersion: "go1.16", + NodeID: "node123", + Version: "v1.0.0", + Goroutines: 10, + Threads: 5, + MemStats: memStats, + GCDurationStats: gcDurationStats, + ProcStats: procStats, + CapsStats: capsStats, + } + + result, err := sm.ToMap(true, "UTC") + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + expected := map[string]any{ + "pid": 1234, + "go_version": "go1.16", + "node_id": "node123", + "version": "v1.0.0", + "goroutines": 10, + "threads": 5, + "mem_stats": memStats.ToMap(), + "gc_duration_stats": gcDurationStats.ToMap(), + "proc_stats": procStats.ToMap(), + "caps_stats": capsStats.ToMap(), + } + + if !reflect.DeepEqual(result, expected) { + t.Errorf("Expected %v, got %v", expected, result) + } + + condensedResult, err := sm.ToMap(false, "UTC") + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + + if condensedResult == nil { + t.Errorf("Expected non-nil map for debug=false") + } +} + +func TestComputeAppMetrics(t *testing.T) { + + metrics, err := computeAppMetrics() + + if err != nil { + t.Fatalf("computeAppMetrics returned an error: %v", err) + } + + if metrics.PID != os.Getpid() { + t.Errorf("Expected PID %d, but got %d", os.Getpid(), metrics.PID) + } + + if metrics.GoVersion != runtime.Version() { + t.Errorf("Expected GoVersion %s, but got %s", runtime.Version(), metrics.GoVersion) + } + + p, err := procfs.NewProc(metrics.PID) + if err != nil { + t.Fatalf("Failed to create procfs proc: %v", err) + } + + stat, err := p.Stat() + if err != nil { + t.Fatalf("Failed to get proc stat: %v", err) + } + + if metrics.ProcStats.VirtualMemory != stat.VirtualMemory() { + t.Errorf("Expected VirtualMemory %d, but got %d", stat.VirtualMemory(), metrics.ProcStats.VirtualMemory) + } + +} + +func TestCaseComputeAppMetrics(t *testing.T) { + + _, err := computeAppMetrics() + + if err != nil { + t.Fatalf("computeAppMetrics returned an error: %v", err) + } + +}