Skip to content

Commit

Permalink
test: Add unit tests
Browse files Browse the repository at this point in the history
* Add coverage target in makefile

Signed-off-by: Mahendra Paipuri <[email protected]>
  • Loading branch information
mahendrapaipuri committed Mar 25, 2024
1 parent 0c45899 commit 313eeb4
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 50 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/step_tests-unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,8 @@ jobs:

- name: Merge coverage files
run: |
# Remove first line from coverage-cgo.out file
tail -n +2 coverage-cgo.out > coverage-cgo.tmp.out && mv coverage-cgo.tmp.out coverage-cgo.out
# Merge coverage-go.out and coverage-cgo.out files
cat coverage-go.out coverage-cgo.out > coverage.out
go tool cover -func=coverage.out -o=coverage.out
# Make global coverage report
make coverage
# Remove testdata that contains too many files
rm -rf pkg/collector/testdata
Expand All @@ -58,6 +55,9 @@ jobs:
# Create/Update badge
gobadge -target README.md -filename coverage.out -link https://github.com/mahendrapaipuri/ceems/actions/workflows/ci.yml?query=branch%3Amain
# Check diff on README
git diff README.md
- name: Verify Changed files
uses: tj-actions/verify-changed-files@v19
id: verify-changed-files
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ coverage.txt

# Output of the go coverage tool, specifically when used with LiteIDE
*.out
*.out.tmp

# Dependency directories (remove the comment below to include it)
vendor/
Expand Down
18 changes: 15 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,19 @@ ifeq ($(CGO_BUILD), 1)
checkrules := skip-checkrules

# go test flags
test-flags := -coverprofile=coverage-cgo.out
coverage-file := coverage-cgo.out
test-flags := -covermode=atomic -coverprofile=$(coverage-file).tmp
else
PROMU_CONF ?= .promu-go.yml
pkgs := ./pkg/collector ./pkg/emissions ./pkg/tsdb ./pkg/grafana ./cmd/ceems_exporter
pkgs := ./pkg/collector ./pkg/emissions ./pkg/tsdb ./pkg/grafana \
./internal/helpers ./internal/osexec ./internal/structset \
./cmd/ceems_exporter
checkmetrics := checkmetrics
checkrules := checkrules

# go test flags
test-flags := -coverprofile=coverage-go.out
coverage-file := coverage-go.out
test-flags := -covermode=atomic -coverprofile=$(coverage-file).tmp
endif

ifeq ($(GOHOSTOS), linux)
Expand Down Expand Up @@ -90,10 +94,18 @@ $(eval $(call goarch_pair,mips64el,mipsel))

all:: vet common-all $(cross-test) $(test-docker) $(checkmetrics) $(checkrules) $(test-e2e)

.PHONY: coverage
coverage:
@echo ">> getting coverage report"
tail -n +2 coverage-cgo.out > coverage-cgo.tmp.out && mv coverage-cgo.tmp.out coverage-cgo.out
cat coverage-go.out coverage-cgo.out > coverage.out
$(GO) tool cover -func=coverage.out -o=coverage.out

.PHONY: test
test: pkg/collector/testdata/sys/.unpacked pkg/collector/testdata/proc/.unpacked
@echo ">> running tests"
$(GO) test -short $(test-flags) $(pkgs)
cat $(coverage-file).tmp | grep -v "main.go" > $(coverage-file)

.PHONY: test-32bit
test-32bit: pkg/collector/testdata/sys/.unpacked
Expand Down
22 changes: 11 additions & 11 deletions internal/structset/structset.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@ func GetStructFieldNames(Struct interface{}) []string {
return fields
}

// GetStructFieldValues returns all values in a given struct
func GetStructFieldValues(Struct interface{}) []interface{} {
v := reflect.ValueOf(Struct)
values := make([]interface{}, v.NumField())

for i := 0; i < v.NumField(); i++ {
f := v.Field(i)
values = append(values, f.Interface())
}
return values
}
// // GetStructFieldValues returns all values in a given struct
// func GetStructFieldValues(Struct interface{}) []interface{} {
// v := reflect.ValueOf(Struct)
// values := make([]interface{}, v.NumField())

// for i := 0; i < v.NumField(); i++ {
// f := v.Field(i)
// values = append(values, f.Interface())
// }
// return values
// }

// Get tag value of field. If tag value is "-", return lower case value of field name
func getTagValue(field reflect.StructField, tag string) string {
Expand Down
45 changes: 45 additions & 0 deletions internal/structset/structset_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package structset

import (
"reflect"
"testing"
)

// testStruct is a test struct that will be used in tests
type testStruct struct {
ID int `json:"id" sql:"id"`
Field1 string `json:"field1" sql:"f1"`
Field2 bool `json:"field2" sql:"f2"`
Field3 interface{} `json:"field3" sql:"f3"`
Field4 []string `json:"field4" sql:"f4"`
}

func TestGetStructFieldNames(t *testing.T) {
fields := GetStructFieldNames(testStruct{})
expectedFields := []string{"ID", "Field1", "Field2", "Field3", "Field4"}
if !reflect.DeepEqual(fields, expectedFields) {
t.Errorf("expected %v, got %v", expectedFields, fields)
}
}

func TestGetStructFieldValues(t *testing.T) {
tags := GetStructFieldTagValues(testStruct{}, "json")
expectedTags := []string{"field1", "field2", "field3", "field4"}
if !reflect.DeepEqual(tags, expectedTags) {
t.Errorf("expected %v, got %v", expectedTags, tags)
}
}

func TestGetStructFieldTagMap(t *testing.T) {
tagMap := GetStructFieldTagMap(testStruct{}, "json", "sql")
expectedTagMap := map[string]string{
"id": "id",
"field1": "f1",
"field2": "f2",
"field3": "f3",
"field4": "f4",
}
if !reflect.DeepEqual(tagMap, expectedTagMap) {
t.Errorf("expected %v, got %v", expectedTagMap, tagMap)
}
}
52 changes: 21 additions & 31 deletions pkg/api/db/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,37 +310,27 @@ func TestJobStatsDBBackup(t *testing.T) {
}
}

// func TestJobStatsDBBackupFailRetries(t *testing.T) {
// tmpDir := t.TempDir()
// c := prepareMockConfig(tmpDir)

// // Make new stats DB
// j, err := NewJobStatsDB(c)
// if err != nil {
// t.Errorf("Failed to create new statsDB struct due to %s", err)
// }

// // Make backup dir non existent
// s.storage.dbBackupPath = "non-existent"

// // Populate DB with data
// populateDBWithMockData(s.db, j)

// // Run backup
// for i := 0; i < maxBackupRetries; i++ {
// s.createBackup()
// }
// if s.storage.backupRetries != 0 {
// t.Errorf("Failed to reset DB backup retries counter. Expected 0, got %d", s.storage.backupRetries)
// }

// for i := 0; i < maxBackupRetries-1; i++ {
// s.createBackup()
// }
// if s.storage.backupRetries != 0 {
// t.Errorf("Failed to increment DB backup retries counter. Expected %d, got %d", maxBackupRetries-1, s.storage.backupRetries)
// }
// }
func TestStatsDBBackup(t *testing.T) {
tmpDir := t.TempDir()
c := prepareMockConfig(tmpDir)

// Make new stats DB
s, err := NewStatsDB(c)
if err != nil {
t.Errorf("Failed to create new statsDB struct due to %s", err)
}

// Make backup dir non existent
s.storage.dbBackupPath = tmpDir

// Populate DB with data
populateDBWithMockData(s)

// Run backup
if err := s.createBackup(); err != nil {
t.Errorf("Failed to backup DB: %s", err)
}
}

func TestJobStatsDeleteOldUnits(t *testing.T) {
tmpDir := t.TempDir()
Expand Down
27 changes: 27 additions & 0 deletions pkg/api/helper/helper_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package helper

import (
"fmt"
"reflect"
"testing"

"github.com/mahendrapaipuri/ceems/pkg/api/base"
)

type nodelistParserTest struct {
Expand Down Expand Up @@ -128,3 +131,27 @@ func TestNodelistParser(t *testing.T) {
}
}
}

func TestTimeToTimestamp(t *testing.T) {
expectedTimeStamp := 1136239445000
timeFormat := fmt.Sprintf("%s-0700", base.DatetimeLayout)
timeStamp := TimeToTimestamp(timeFormat, "2006-01-02T15:04:05-0700")
if timeStamp != int64(expectedTimeStamp) {
t.Errorf("expected timestamp %d, got %d", expectedTimeStamp, timeStamp)
}

// Check failure case
timeStamp = TimeToTimestamp(timeFormat, "2006-01-0215:04:05-0700")
if timeStamp != 0 {
t.Errorf("expected timestamp 0, got %d", timeStamp)
}
}

func TestChunkBy(t *testing.T) {
expectedChunks := [][]int{{1, 2, 3}, {4, 5, 6}}
inputSlice := []int{1, 2, 3, 4, 5, 6}
chunks := ChunkBy(inputSlice, 3)
if !reflect.DeepEqual(expectedChunks, chunks) {
t.Errorf("expected chunks %v, got %v", expectedChunks, chunks)
}
}
13 changes: 13 additions & 0 deletions pkg/api/http/error_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package http

import (
"fmt"
"testing"
)

func TestApiError(t *testing.T) {
e := apiError{typ: errorBadData, err: fmt.Errorf("bad data")}
if e.Error() != "bad_data: bad data" {
t.Errorf("expected error bad_data: bad data, got %s", e.Error())
}
}

0 comments on commit 313eeb4

Please sign in to comment.