PouchContainer Engineering Quality Practice

1. Consistent Coding Style Specification

1.1 Golinter — Keeps a Consistent Coding Format

1.2 Shellcheck — Reduces the Potential Problems of Shell Scripts

#!/usr/bin/env bashpouch_version=0.5.xdosomething() {
echo "do something"
}
dosomething
In test.sh line 3:
pouch_version=0.5.x
^-- SC2034: pouch_version appears unused. Verify it or export it.

1.3 Markdownlint — Keeps Consistent typography

2. How to Compile a Golang Unit Test

2.1 Table-Driven Test — DRY Principle

// from https://golang.org/doc/code.html#Testing
package stringutil
import "testing"func TestReverse(t *testing.T) {
cases := []struct {
in, want string
}{
{"Hello, world", "dlrow ,olleH"},
{"Hello, world", "dlorw ,olleH"},
{"", ""},
}
for _, c := range cases {
got := Reverse(c.in)
if got != c.want {
t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want)
}
}
}
{
name: "Normal",
input: "docker.io/library/nginx:alpine",
expected: taggedReference{
Named: namedReference{"docker.io/library/nginx"},
tag: "alpine",
},
err: nil,
}, {
name: "Punycode",
input: "xn--bcher-kva.tld/redis:3",
expected: taggedReference{
Named: namedReference{"xn--bcher-kva.tld/redis"},
tag: "3",
},
err: nil,
}

2.2 Mock — Simulates External Dependencies

http.Client -> http.RoundTripper [http.DefaultTransport]
// https://github.com/alibaba/pouch/blob/master/client/client_mock_test.go#L12-L22
type transportFunc func(*http.Request) (*http.Response, error)
func (transFunc transportFunc) RoundTrip(req *http.Request) (*http.Response, error) {
return transFunc(req)
}
func newMockClient(handler func(*http.Request) (*http.Response, error)) *http.Client {
return &http.Client{
Transport: transportFunc(handler),
}
}
// https://github.com/alibaba/pouch/blob/master/client/image_remove_test.go
func TestImageRemove(t *testing.T) {
expectedURL := "/images/image_id"
httpClient := newMockClient(func(req *http.Request) (*http.Response, error) {
if !strings.HasPrefix(req.URL.Path, expectedURL) {
return nil, fmt.Errorf("expected URL '%s', got '%s'", expectedURL, req.URL)
}
if req.Method != "DELETE" {
return nil, fmt.Errorf("expected DELETE method, got %s", req.Method)
}
return &http.Response{
StatusCode: http.StatusNoContent,
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
}, nil
})
client := &APIClient{
HTTPCli: httpClient,
}
err := client.ImageRemove(context.Background(), "image_id", false)
if err != nil {
t.Fatal(err)
}
}
// https://github.com/alibaba/pouch/blob/master/apis/server/image_bridge_test.go
type mockImgePull struct {
mgr.ImageMgr
handler func(ctx context.Context, imageRef string, authConfig *types.AuthConfig, out io.Writer) error
}
func (m *mockImgePull) PullImage(ctx context.Context, imageRef string, authConfig *types.AuthConfig, out io.Writer) error {
return m.handler(ctx, imageRef, authConfig, out)
}
func Test_pullImage_without_tag(t *testing.T) {
var s Server
s.ImageMgr = &mockImgePull{
ImageMgr: &mgr.ImageManager{},
handler: func(ctx context.Context, imageRef string, authConfig *types.AuthConfig, out io.Writer) error {
assert.Equal(t, "reg.abc.com/base/os:7.2", imageRef)
return nil
},
}
req := &http.Request{
Form: map[string][]string{"fromImage": {"reg.abc.com/base/os:7.2"}},
Header: map[string][]string{},
}
s.pullImage(context.Background(), nil, req)
}
type Do interface {
Add(x int, y int) int
Sub(x int, y int) int
}
type mockDo struct {
addFunc func(x int, y int) int
subFunc func(x int, y int) int
}
// Add implements Do.Add function.
type (m *mockDo) Add(x int, y int) int {
return m.addFunc(x, y)
}
// Sub implements Do.Sub function.
type (m *mockDo) Sub(x int, y int) int {
return m.subFunc(x, y)
}

2.3 Other tricks

Conclusion

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store