Skip to content

Commit

Permalink
closes #18 adding unit tests for backend (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
gbolo committed Dec 7, 2018
1 parent d15d98f commit 4335459
Show file tree
Hide file tree
Showing 21 changed files with 677 additions and 21 deletions.
13 changes: 10 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ Q = $(if $(filter 1,$V),,@)
M = $(shell printf "\033[34;1m▶\033[0m")

.PHONY: all
all: fmt dep $(BIN) frontend ; $(info $(M) building executable...) @ ## Build program binary
all: fmt dep $(BIN) frontend ; $(info $(M) building executable...) @ ## Build main binary
$Q $(GO) build \
-ldflags '-X main.Version=$(VERSION) -X main.BuildDate=$(DATE) -X main.CommitSHA=$(COMMIT_SHA)' \
-o $(BIN)/$(PACKAGE)

.PHONY: docker
docker: clean ; $(info $(M) building docker image...) @ ## Build docker imaage
docker: clean ; $(info $(M) building docker image...) @ ## Build docker image
$Q docker build -t gbolo/$(PACKAGE):$(VERSION) .

.PHONY: frontend
Expand All @@ -41,6 +41,9 @@ $(BIN)/%: | $(BIN) ; $(info $(M) building $(REPOSITORY)...)
DEP = $(BIN)/dep
$(BIN)/dep: REPOSITORY=github.com/golang/dep/cmd/dep

GOIMPORTS = $(BIN)/goimports
$(BIN)/goimports: REPOSITORY=golang.org/x/tools/cmd/goimports

.PHONY: dep
dep: | $(DEP) ; $(info $(M) running dep...) @ ## Run dep ensure to fetch dependencies
$Q $(DEP) ensure -v
Expand All @@ -49,8 +52,12 @@ dep: | $(DEP) ; $(info $(M) running dep...) @ ## Run dep ensure to fetch depende
fmt: ; $(info $(M) running gofmt...) @ ## Run gofmt on all source files
$Q $(GO) fmt ./...

.PHONY: goimports
goimports: | $(GOIMPORTS) ; $(info $(M) running goimports...) @ ## Run goimports on backend source files
$Q $(GOIMPORTS) -w backend/

.PHONY: test
test: ; $(info $(M) running go test...) @ ## Run go test
test: ; $(info $(M) running go test...) @ ## Run go unit tests
$Q $(GO) test -v -cover $(TESTPKGS)

# Misc
Expand Down
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,23 @@ If you prefer to use `docker` for building (which I recommend), you can build th
make docker
```


### Make Targets

```
$ make help
all Build main binary
docker Build docker image
frontend Build frontend
dep Run dep ensure to fetch dependencies
fmt Run gofmt on all source files
goimports Run goimports on backend source files
test Run go unit tests
clean Cleanup everything
```


### API Documentation
For further details on an API endpoint (including example responses), click on the endpoint's name.

Expand Down
191 changes: 191 additions & 0 deletions backend/aws_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
package backend

import (
"os"
"testing"
)

func TestCheckInstanceType(t *testing.T) {
// init the test config
os.Setenv("POWER_TOGGLE_AWS_IGNORE_INSTANCE_TYPES", "c5d.18xlarge c5d.9xlarge")
ConfigInit("../testdata/sampleconfig/power-toggle-config.yaml", false)

testCases := map[string]bool{
"c5d.18xlarge": false,
"c5d.9xlarge": false,
"c5.18xlarge": true,
"t2.medium": true,
}

for input, expectedResult := range testCases {
if checkInstanceType(input) != expectedResult {
t.Errorf("input(%s) != expectedResult(%v)", input, expectedResult)
}
}
}

func TestValidateEnvName(t *testing.T) {
// init the test config
os.Setenv("POWER_TOGGLE_AWS_IGNORE_ENVIRONMENTS", "ignoredEnv1 ignoredEnv2")
ConfigInit("../testdata/sampleconfig/power-toggle-config.yaml", false)

testCases := map[string]bool{
"ignoredEnv1": false,
"ignoredEnv2": false,
"env3": true,
"env4": true,
}

for input, expectedResult := range testCases {
if validateEnvName(input) != expectedResult {
t.Errorf("input(%s) != expectedResult(%v)", input, expectedResult)
}
}
}

func TestGetEnvironmentById(t *testing.T) {
if err := resetMockData(); err != nil {
t.Fatalf("mockRefreshTable failed: %v", err)
}
envId := "356f6265efcc"

if len(cachedTable) == 0 {
t.Fatalf("cachedTable is of 0 size!")
}

env, found := getEnvironmentById(envId)
if !found {
t.Errorf("unable to retrieve test env %s", envId)
}
if env.Name != "mockenv1" && len(env.Instances) < 1 {
t.Errorf("unexpected env retrieved")
}
if _, found := getEnvironmentById("incorrectEnvId"); found {
t.Errorf("getEnvironmentById reported found for an invalid env id")
}
}

func TestUpdateEnvDetails(t *testing.T) {
if err := resetMockData(); err != nil {
t.Fatalf("mockRefreshTable failed: %v", err)
}

// ensure our mocked json initial state is correct
startingInstanceState := cachedTable[1].Instances[1].State
if startingInstanceState != "stopped" {
t.Error("our moc json has unexpected init values. Has it changed?")
}
startingEnvState := cachedTable[1].State
if startingEnvState != "stopped" {
t.Error("our moc json has unexpected init values. Has it changed?")
}

// set an instance in this env to running, we should see env state change
cachedTable[1].Instances[1].State = "running"
updateEnvDetails()
if cachedTable[1].State != ENV_MIXED {
t.Errorf("unexpected env state: got %s expected %s", cachedTable[1].State, ENV_MIXED)
}

// set an instance in this env to pending, we should see env state change
cachedTable[1].Instances[1].State = "pending"
updateEnvDetails()
if cachedTable[1].State != ENV_CHANGING {
t.Errorf("unexpected env state: got %s expected %s", cachedTable[1].State, ENV_CHANGING)
}

// set all instances to running, we should see env state change
for i, _ := range cachedTable[1].Instances {
cachedTable[1].Instances[i].State = "running"
}
updateEnvDetails()
if cachedTable[1].State != ENV_RUNNING {
t.Errorf("unexpected env state: got %s expected %s", cachedTable[1].State, ENV_RUNNING)
}

// set all instances to stopped, we should see env state change
for i, _ := range cachedTable[1].Instances {
cachedTable[1].Instances[i].State = "stopped"
}
updateEnvDetails()
if cachedTable[1].State != ENV_DOWN {
t.Errorf("unexpected env state: got %s expected %s", cachedTable[1].State, ENV_DOWN)
}

// ensure that our counts are functioning correctly
currentTotalCpuCount := cachedTable[1].TotalVCPU
cachedTable[1].Instances[1].VCPU++
updateEnvDetails()
if (currentTotalCpuCount + 1) != cachedTable[1].TotalVCPU {
t.Errorf("Total vCPU count has an unexpected value: %d", cachedTable[1].TotalVCPU)
}
}

func TestToggleInstance(t *testing.T) {
if err := resetMockData(); err != nil {
t.Fatalf("mockRefreshTable failed: %v", err)
}

// test toggleInstance
for desiredState, actualState := range map[string]string{
"stop": "stopped",
"start": "running",
} {
_, err := toggleInstance(cachedTable[1].Instances[1].Id, desiredState)
if err != nil || cachedTable[1].Instances[1].State != actualState {
t.Errorf("go %s but wanted %s. Err: %v", cachedTable[1].Instances[1].State, actualState, err)
}
}
}

func TestGetAWSInstanceId(t *testing.T) {
if err := resetMockData(); err != nil {
t.Fatalf("mockRefreshTable failed: %v", err)
}

if getAWSInstanceId(cachedTable[1].Instances[1].Id) != cachedTable[1].Instances[1].InstanceId {
t.Errorf("getAWSInstanceId is not returning correct id")
}
}

func TestEnvStartStop(t *testing.T) {
if err := resetMockData(); err != nil {
t.Fatalf("mockRefreshTable failed: %v", err)
}
envId := "4f9f1afb29f1"

_, err := startupEnv(envId)
if err != nil {
t.Errorf("startupEnv return and error: %v", err)
}
updateEnvDetails()
state, _ := getEnvState(envId)
if state != "running" {
t.Errorf("test env is not in running state: %s", state)
}

_, err = shutdownEnv(envId)
if err != nil {
t.Errorf("startupEnv return and error: %v", err)
}
updateEnvDetails()
state, _ = getEnvState(envId)
if state != "stopped" {
t.Errorf("test env is not in stopped state: %s", state)
}
}

func resetMockData() error {
MOCK_ENABLED = true
cachedTable = cachedTable[:0]
return mockRefreshTable()
}

func getEnvState(envId string) (string, bool) {
env, found := getEnvironmentById(envId)
if !found {
return "", found
} else {
return env.State, found
}
}
2 changes: 1 addition & 1 deletion backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ func StartBackendDeamon(cfgFile string) {
// }, nil
//}
//
//cfg.EndpointResolver = aws.EndpointResolverFunc(mockAwsResolver)
//cfg.EndpointResolver = aws.EndpointResolverFunc(mockAwsResolver)
27 changes: 27 additions & 0 deletions backend/common_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package backend

import "testing"

func TestComputeId(t *testing.T) {

// test cases for case sensitivity
testStringCase := map[string]string{
"testString": "956265657d0b",
"teststring": "b8473b86d4c2",
}

// test case for multiple strings
testMultipleInputs1 := "teststring1"
testMultipleInputs2 := "teststring2"
testMultipleInputsExpectedId := "ab8675367360"

for input, expectedResult := range testStringCase {
if ComputeId(input) != expectedResult {
t.Errorf("%s != %s - got: %s", input, expectedResult, ComputeId(input))
}
}

if ComputeId(testMultipleInputs1, testMultipleInputs2) != testMultipleInputsExpectedId {
t.Error("testMultipleInputsExpectedId did not match")
}
}
15 changes: 0 additions & 15 deletions backend/config.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package backend

import (
"fmt"
"os"
"strings"

"github.com/spf13/viper"
Expand Down Expand Up @@ -54,19 +52,6 @@ func initViper(cfgFile string) {
viper.SetConfigName("power-toggle-config")
viper.AddConfigPath("./")

// if env <env_prefix>_TESTING=true then set a path to sampleconfig
if viper.GetBool("testing") {
testConfig := "./testdata/sampleconfig"

goPath := os.Getenv("GOPATH")
if goPath != "" {
testConfig = fmt.Sprintf("%s/src/github.com/gbolo/aws-power-toggle/testdata/sampleconfig", goPath)
}

log.Debugf("dev mode enabled: %s", testConfig)
viper.AddConfigPath(testConfig)
}

// if the user provides a config file in a flag, lets use it
if cfgFile != "" {
viper.SetConfigFile(cfgFile)
Expand Down
21 changes: 21 additions & 0 deletions backend/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package backend

import (
"fmt"
"os"
"testing"
)

func TestConfigInit(t *testing.T) {
maxInstancesToShutdown = -1

testConfig := "../testdata/sampleconfig"
goPath := os.Getenv("GOPATH")
if goPath != "" {
testConfig = fmt.Sprintf("%s/src/github.com/gbolo/aws-power-toggle/testdata/sampleconfig", goPath)
}
ConfigInit(testConfig, true)
if maxInstancesToShutdown == -1 {
t.Error("ConfigInit did not change maxInstancesToShutdown")
}
}
3 changes: 2 additions & 1 deletion backend/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package backend

import (
"fmt"
"github.com/gorilla/mux"
"net/http"

"github.com/gorilla/mux"
)

// returns version information
Expand Down
Loading

0 comments on commit 4335459

Please sign in to comment.