Skip to content

Commit 4ddd633

Browse files
authored
Merge pull request #9 from marshyski/master
Add tests and better error handling for configs
2 parents 62a64f1 + 168aca5 commit 4ddd633

File tree

9 files changed

+309
-27
lines changed

9 files changed

+309
-27
lines changed

.circleci/config.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,17 @@ jobs:
44
docker:
55
- image: circleci/golang:1.9.1
66
working_directory: /go/src/github.com/FINRAOS/yum-nginx-api
7+
environment:
8+
TEST_RESULTS: /tmp/test-results
79
steps:
810
- setup_remote_docker
911
- run: git clone https://github.com/FINRAOS/yum-nginx-api.git -b $CIRCLE_BRANCH .
12+
- run:
13+
shell: /bin/bash
14+
command: |
15+
mkdir -p $TEST_RESULTS
16+
go get github.com/jstemmer/go-junit-report
17+
make test | go-junit-report > ${TEST_RESULTS}/go-test-report.xml
1018
- run:
1119
shell: /bin/bash
1220
command: |
@@ -17,4 +25,6 @@ jobs:
1725
shell: /bin/bash
1826
command: |
1927
docker login -u $DOCKER_USER -p $DOCKER_PASS
20-
docker push finraos/yum-nginx-api:latest
28+
docker push finraos/yum-nginx-api:latest
29+
- store_test_results:
30+
path: /tmp/test-results

Makefile

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,16 @@
11
PACKAGE_NAME:='yumapi'
22
BUILT_ON:=$(shell date)
33
COMMIT_HASH:=$(shell git log -n 1 --pretty=format:"%H")
4-
PACKAGES:=$(shell go list ./... | sed -n '1!p' | grep -v /vendor/)
4+
PACKAGES:=$(shell go list ./... | grep -v /vendor/)
55
LDFLAGS:='-X "main.builtOn=$(BUILT_ON)" -X "main.commitHash=$(COMMIT_HASH)"'
66

77
default: docker
88

99
test:
10-
echo "mode: count" > coverage-all.out
11-
$(foreach pkg,$(PACKAGES), \
12-
go test -p=1 -cover -covermode=count -coverprofile=coverage.out ${pkg}; \
13-
tail -n +2 coverage.out >> coverage-all.out;)
14-
15-
cover: test
16-
go tool cover -html=coverage-all.out
10+
go test -cover -v $(PACKAGES)
1711

1812
run: config
19-
go run -ldflags $(LDFLAGS) *.go
13+
go run -ldflags $(LDFLAGS) `find . | grep -v 'test\|vendor\|repo' | grep \.go`
2014

2115
# Cross-compile from OS X to Linux using xgo
2216
cc:

config.go

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,22 @@
1212
package main
1313

1414
import (
15-
"fmt"
15+
"errors"
1616
"os"
1717
"path"
1818

1919
"github.com/FINRAOS/yum-nginx-api/repojson"
2020
"github.com/spf13/viper"
2121
)
2222

23+
const (
24+
crError = "config: createrepo_workers is less than 1"
25+
mlError = "config: max_content_length is less than 1MB"
26+
upError = "config: upload_directory does not exist"
27+
ptError = "config: port is not above port 80"
28+
mxError = "config: max_retries is less than 1"
29+
)
30+
2331
// Some vars are used with different types in handlers vs validation
2432
var (
2533
builtOn string
@@ -36,14 +44,15 @@ var (
3644
crBin string
3745
)
3846

39-
func init() {
47+
// Validate configurations and if createrepo binary is present in path
48+
func configValidate() error {
4049
viper.SetConfigName("yumapi")
4150
viper.AddConfigPath("/opt/yum-nginx-api/yumapi/")
4251
viper.AddConfigPath("/etc/yumapi/")
4352
viper.AddConfigPath(".")
4453
err := viper.ReadInConfig()
4554
if err != nil {
46-
panic(fmt.Errorf("Fatal error config file: %s \n", err))
55+
return errors.New("Fatal error config file: " + err.Error())
4756
}
4857

4958
viper.SetDefault("createrepo_workers", 1)
@@ -52,10 +61,7 @@ func init() {
5261
viper.SetDefault("port", 8080)
5362
viper.SetDefault("dev_mode", false)
5463
viper.SetDefault("max_retries", 3)
55-
}
5664

57-
// Validate configurations and if createrepo binary is present in path
58-
func configValidate() {
5965
createRepo = viper.GetString("createrepo_workers")
6066
maxLength = viper.GetInt64("max_content_length")
6167
uploadDir = path.Clean(viper.GetString("upload_dir")) + "/"
@@ -64,16 +70,19 @@ func configValidate() {
6470
maxRetries = viper.GetInt("max_retries")
6571

6672
if viper.GetInt64("createrepo_workers") < 1 {
67-
panic(fmt.Errorf("createrepo_workers is less than 1"))
73+
return errors.New(crError)
6874
}
6975
if maxLength < 1000000 {
70-
panic(fmt.Errorf("max_content_length is less than 1MB"))
76+
return errors.New(mlError)
7177
}
7278
if _, err := os.Stat(uploadDir); os.IsNotExist(err) {
73-
panic(fmt.Errorf("upload_directory %s does not exist", uploadDir))
79+
return errors.New(upError)
7480
}
7581
if viper.GetInt64("port") < 80 {
76-
panic(fmt.Errorf("port is not above port 80"))
82+
return errors.New(ptError)
83+
}
84+
if maxRetries < 1 {
85+
return errors.New(mxError)
7786
}
7887
if !devMode {
7988
for _, cr := range crPaths {
@@ -83,10 +92,8 @@ func configValidate() {
8392
}
8493
}
8594
if crBin == "" {
86-
panic(fmt.Errorf("createrepo binary not found in path"))
95+
return errors.New(crError)
8796
}
8897
}
89-
if maxRetries < 1 {
90-
panic(fmt.Errorf("max_retries is less than 1"))
91-
}
98+
return nil
9299
}

config_test.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package main
2+
3+
import (
4+
"io/ioutil"
5+
"os"
6+
"testing"
7+
)
8+
9+
const testFile = "./yumapi.yaml"
10+
11+
// TestConfigValidate validates all configuration
12+
// options in yumapi config file
13+
func TestConfigValidate(t *testing.T) {
14+
b := []byte("upload_dir: .\ncreaterepo_workers: 2\ndev_mode: true\nmax_content_length: 220000000\nport: 80\nmax_retries: 1")
15+
if err := ioutil.WriteFile(testFile, b, 0644); err != nil {
16+
t.Fatalf("Error writing file")
17+
}
18+
if err := configValidate(); err != nil {
19+
os.Remove(testFile)
20+
t.Fatal(err)
21+
}
22+
os.Remove(testFile)
23+
}
24+
25+
// TestConfigCR verifies error returned for zero workers
26+
func TestConfigCR(t *testing.T) {
27+
b := []byte("createrepo_workers: 0")
28+
if err := ioutil.WriteFile(testFile, b, 0644); err != nil {
29+
t.Fatalf("Error writing file")
30+
}
31+
if err := configValidate(); err.Error() != crError {
32+
os.Remove(testFile)
33+
t.Fatal(err)
34+
}
35+
os.Remove(testFile)
36+
}
37+
38+
// TestConfigML verifies max_content_length is not too low
39+
func TestConfigML(t *testing.T) {
40+
b := []byte("max_content_length: 900000")
41+
if err := ioutil.WriteFile(testFile, b, 0644); err != nil {
42+
t.Fatalf("Error writing file")
43+
}
44+
if err := configValidate(); err.Error() != mlError {
45+
os.Remove(testFile)
46+
t.Fatal(err)
47+
}
48+
os.Remove(testFile)
49+
}
50+
51+
// TestConfigUp verifies upload_dir does not exist
52+
func TestConfigUP(t *testing.T) {
53+
b := []byte("upload_dir: /supp")
54+
if err := ioutil.WriteFile(testFile, b, 0644); err != nil {
55+
t.Fatalf("Error writing file")
56+
}
57+
if err := configValidate(); err.Error() != upError {
58+
os.Remove(testFile)
59+
t.Fatal(err)
60+
}
61+
os.Remove(testFile)
62+
}
63+
64+
// TestConfigPT verifies ports under 80 are not allowed
65+
func TestConfigPT(t *testing.T) {
66+
b := []byte("port: 22")
67+
if err := ioutil.WriteFile(testFile, b, 0644); err != nil {
68+
t.Fatalf("Error writing file")
69+
}
70+
if err := configValidate(); err.Error() != ptError {
71+
os.Remove(testFile)
72+
t.Fatal(err)
73+
}
74+
os.Remove(testFile)
75+
}
76+
77+
// TestConfigMX verifies max retries are not less than 1
78+
func TestConfigMX(t *testing.T) {
79+
b := []byte("max_retries: 0")
80+
if err := ioutil.WriteFile(testFile, b, 0644); err != nil {
81+
t.Fatalf("Error writing file")
82+
}
83+
if err := configValidate(); err.Error() != mxError {
84+
os.Remove(testFile)
85+
t.Fatal(err)
86+
}
87+
os.Remove(testFile)
88+
}

handlers_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package main
2+
3+
import (
4+
"net/http"
5+
"net/http/httptest"
6+
"testing"
7+
8+
"github.com/go-ozzo/ozzo-routing"
9+
"github.com/go-ozzo/ozzo-routing/content"
10+
)
11+
12+
func newRouter() *routing.Router {
13+
rtr := routing.New()
14+
rtr.Group("/api", content.TypeNegotiator(content.JSON))
15+
return rtr
16+
}
17+
func testHealthHandler(t *testing.T, rtr *routing.Router) {
18+
rtr.Get("/health", healthRoute)
19+
req, err := http.NewRequest("GET", "/health", nil)
20+
req.Header.Set("Content-Type", "application/json")
21+
if err != nil {
22+
t.Fatal(err)
23+
}
24+
25+
rr := httptest.NewRecorder()
26+
rtr.ServeHTTP(rr, req)
27+
if status := rr.Code; status != http.StatusOK {
28+
t.Errorf("handler returned wrong status code: got %v want %v",
29+
status, http.StatusOK)
30+
}
31+
32+
expected := `OK`
33+
if rr.Body.String() != expected {
34+
t.Errorf("handler returned unexpected body: got %v want %v",
35+
rr.Body.String(), expected)
36+
}
37+
}
38+
39+
func testRepoHandler(t *testing.T, rtr *routing.Router) {
40+
rtr.Get("/repo", repoRoute)
41+
req, err := http.NewRequest("GET", "/repo", nil)
42+
req.Header.Set("Content-Type", "application/json")
43+
if err != nil {
44+
t.Fatal(err)
45+
}
46+
47+
rr := httptest.NewRecorder()
48+
rtr.ServeHTTP(rr, req)
49+
if status := rr.Code; status != http.StatusOK {
50+
t.Errorf("handler returned wrong status code: got %v want %v",
51+
status, http.StatusOK)
52+
}
53+
54+
expected := `[]`
55+
if rr.Body.String() != expected {
56+
t.Errorf("handler returned unexpected body: got %v want %v",
57+
rr.Body.String(), expected)
58+
}
59+
}
60+
61+
func TestHealth(t *testing.T) {
62+
testHealthHandler(t, newRouter())
63+
}
64+
65+
func TestRepo(t *testing.T) {
66+
testRepoHandler(t, newRouter())
67+
}

main.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,15 @@ func uploadRoute(c *routing.Context) error {
6161
file, handler, err := c.Request.FormFile("file")
6262
if err != nil {
6363
c.Response.WriteHeader(http.StatusInternalServerError)
64-
c.Write("Upload Failed")
64+
c.Write("Upload Failed " + err.Error())
6565
return err
6666
}
6767
defer file.Close()
6868
filePath := uploadDir + handler.Filename
6969
f, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0644)
7070
if err != nil {
7171
c.Response.WriteHeader(http.StatusInternalServerError)
72-
c.Write("Upload Failed")
72+
c.Write("Upload Failed " + err.Error())
7373
return err
7474
}
7575
defer f.Close()
@@ -104,7 +104,9 @@ func repoRoute(c *routing.Context) error {
104104
}
105105

106106
func main() {
107-
configValidate()
107+
if err := configValidate(); err != nil {
108+
log.Fatalln(err.Error())
109+
}
108110
go crRoutine()
109111
rtr := routing.New()
110112

repojson/primary.sqlite.bz2

1.53 KB
Binary file not shown.

repojson/primary.sqlite.xz

1.43 KB
Binary file not shown.

0 commit comments

Comments
 (0)