Skip to content

Commit bc459b5

Browse files
committed
Merge pull request #11 from gatewayd-io/add-ci
Add CI with lint, test and (commented out) coverage reporting
2 parents 244950d + 4d0d2ae commit bc459b5

File tree

15 files changed

+623
-327
lines changed

15 files changed

+623
-327
lines changed

.github/workflows/test.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Test GatewayD
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
tags:
8+
- v*
9+
pull_request:
10+
11+
jobs:
12+
test:
13+
name: Test GatewayD
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout 🛎️
17+
uses: actions/checkout@v3
18+
with:
19+
fetch-depth: 0
20+
21+
- name: Install Go 🧑‍💻
22+
uses: actions/setup-go@v3
23+
with:
24+
go-version: '1.18'
25+
26+
- name: Lint code issues 🚨
27+
uses: golangci/golangci-lint-action@v3
28+
29+
- name: Run Go tests 🔬
30+
run: go test -cover -covermode atomic -coverprofile=profile.cov -v ./...
31+
32+
# Enable coverage reporting
33+
# - name: Report coverage to coveralls 📈
34+
# uses: shogo82148/actions-goveralls@v1
35+
# with:
36+
# path-to-profile: profile.cov

.golangci.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
linters:
2+
enable-all: true
3+
disable:
4+
- cyclop
5+
- wsl
6+
- godox
7+
- gochecknoglobals
8+
- ireturn
9+
- nlreturn
10+
- testpackage
11+
- paralleltest
12+
- exhaustivestruct
13+
- exhaustruct
14+
- gocognit
15+
- gochecknoinits
16+
- gocyclo
17+

main.go

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,27 @@ import (
88

99
"github.com/gatewayd-io/gatewayd/network"
1010
"github.com/panjf2000/gnet/v2"
11+
"github.com/sirupsen/logrus"
1112
)
1213

14+
const (
15+
DefaultTCPKeepAlive = 3 * time.Second
16+
)
17+
18+
//nolint:funlen
1319
func main() {
1420
// Create a server
15-
server := &network.Server{
16-
Network: "tcp",
17-
Address: "0.0.0.0:15432",
18-
Status: network.Stopped,
19-
Options: []gnet.Option{
21+
server := network.NewServer(
22+
"tcp",
23+
"0.0.0.0:15432",
24+
0,
25+
0,
26+
network.DefaultTickInterval,
27+
network.DefaultPoolSize,
28+
network.DefaultBufferSize,
29+
false,
30+
false,
31+
[]gnet.Option{
2032
// Scheduling options
2133
gnet.WithMulticore(true),
2234
gnet.WithLockOSThread(false),
@@ -37,18 +49,20 @@ func main() {
3749

3850
// Buffer options
3951
// TODO: This should be configurable and optimized.
40-
gnet.WithReadBufferCap(4096),
41-
gnet.WithWriteBufferCap(4096),
42-
gnet.WithSocketRecvBuffer(4096),
43-
gnet.WithSocketSendBuffer(4096),
52+
gnet.WithReadBufferCap(network.DefaultBufferSize),
53+
gnet.WithWriteBufferCap(network.DefaultBufferSize),
54+
gnet.WithSocketRecvBuffer(network.DefaultBufferSize),
55+
gnet.WithSocketSendBuffer(network.DefaultBufferSize),
4456

4557
// TCP options
4658
gnet.WithReuseAddr(true),
4759
gnet.WithReusePort(true),
48-
gnet.WithTCPKeepAlive(time.Second * 3),
60+
gnet.WithTCPKeepAlive(DefaultTCPKeepAlive),
4961
gnet.WithTCPNoDelay(gnet.TCPNoDelay),
5062
},
51-
}
63+
nil,
64+
nil,
65+
)
5266

5367
// Shutdown the server gracefully
5468
var signals []os.Signal
@@ -75,5 +89,7 @@ func main() {
7589
}()
7690

7791
// Run the server
78-
server.Run()
92+
if err := server.Run(); err != nil {
93+
logrus.Error(err)
94+
}
7995
}

network/client.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
package network
22

33
import (
4+
"fmt"
45
"net"
56

67
"github.com/sirupsen/logrus"
78
)
89

10+
const (
11+
DefaultSeed = 1000
12+
)
13+
914
type Client struct {
1015
net.Conn
1116

1217
ID string
1318
ReceiveBufferSize int
1419
Network string // tcp/udp/unix
1520
Address string
16-
1721
// TODO: add read/write deadline and deal with timeouts
1822
}
1923

@@ -51,19 +55,18 @@ func NewClient(network, address string, receiveBufferSize int) *Client {
5155

5256
client.Conn = conn
5357
if client.ReceiveBufferSize == 0 {
54-
client.ReceiveBufferSize = 4096
58+
client.ReceiveBufferSize = DefaultBufferSize
5559
}
5660
logrus.Debugf("New client created: %s", client.Address)
57-
client.ID = GetID(conn.LocalAddr().Network(), conn.LocalAddr().String(), 1000)
61+
client.ID = GetID(conn.LocalAddr().Network(), conn.LocalAddr().String(), DefaultSeed)
5862

5963
return &client
6064
}
6165

6266
func (c *Client) Send(data []byte) error {
63-
_, err := c.Write(data)
64-
if err != nil {
67+
if _, err := c.Write(data); err != nil {
6568
logrus.Errorf("Couldn't send data to the server: %s", err)
66-
return err
69+
return fmt.Errorf("couldn't send data to the server: %w", err)
6770
}
6871
logrus.Debugf("Sent %d bytes to %s", len(data), c.Address)
6972
// logrus.Infof("Sent data: %s", data)
@@ -75,7 +78,7 @@ func (c *Client) Receive() (int, []byte, error) {
7578
read, err := c.Read(buf)
7679
if err != nil {
7780
logrus.Errorf("Couldn't receive data from the server: %s", err)
78-
return 0, nil, err
81+
return 0, nil, fmt.Errorf("couldn't receive data from the server: %w", err)
7982
}
8083
logrus.Debugf("Received %d bytes from %s", read, c.Address)
8184
// logrus.Infof("Received data: %s", buf[:read])

network/client_test.go

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ func TestNewClient(t *testing.T) {
1919
}
2020
}()
2121

22-
c := NewClient("tcp", "localhost:5432", 4096)
23-
defer c.Close()
24-
25-
assert.Equal(t, "tcp", c.Network)
26-
assert.Equal(t, "127.0.0.1:5432", c.Address)
27-
assert.Equal(t, 4096, c.ReceiveBufferSize)
28-
assert.NotEmpty(t, c.ID)
29-
assert.NotNil(t, c.Conn)
22+
client := NewClient("tcp", "localhost:5432", DefaultBufferSize)
23+
defer client.Close()
24+
25+
assert.Equal(t, "tcp", client.Network)
26+
assert.Equal(t, "127.0.0.1:5432", client.Address)
27+
assert.Equal(t, DefaultBufferSize, client.ReceiveBufferSize)
28+
assert.NotEmpty(t, client.ID)
29+
assert.NotNil(t, client.Conn)
3030
}
3131

3232
func TestSend(t *testing.T) {
@@ -41,11 +41,11 @@ func TestSend(t *testing.T) {
4141
}
4242
}()
4343

44-
c := NewClient("tcp", "localhost:5432", 4096)
45-
defer c.Close()
44+
client := NewClient("tcp", "localhost:5432", DefaultBufferSize)
45+
defer client.Close()
4646

47-
assert.NotNil(t, c)
48-
err := c.Send(CreatePostgreSQLPacket('Q', []byte("select 1;")))
47+
assert.NotNil(t, client)
48+
err := client.Send(CreatePostgreSQLPacket('Q', []byte("select 1;")))
4949
assert.Nil(t, err)
5050
}
5151

@@ -61,22 +61,22 @@ func TestReceive(t *testing.T) {
6161
}
6262
}()
6363

64-
c := NewClient("tcp", "localhost:5432", 4096)
65-
defer c.Close()
64+
client := NewClient("tcp", "localhost:5432", DefaultBufferSize)
65+
defer client.Close()
6666

67-
assert.NotNil(t, c)
68-
err := c.Send(CreatePostgreSQLPacket('Q', []byte("select 1;")))
67+
assert.NotNil(t, client)
68+
err := client.Send(CreatePgStartupPacket())
6969
assert.Nil(t, err)
7070

71-
size, data, err := c.Receive()
72-
msg := "SFATAL\x00VFATAL\x00C0A000\x00Munsupported frontend protocol 0.0: server supports 3.0 to 3.0\x00Fpostmaster.c\x00L2138\x00RProcessStartupPacket\x00\x00"
73-
assert.Equal(t, 132, size)
71+
size, data, err := client.Receive()
72+
msg := "\x00\x00\x00\x03"
73+
assert.Equal(t, 9, size)
7474
assert.Equal(t, len(data[:size]), size)
7575
assert.Nil(t, err)
7676
assert.NotEmpty(t, data[:size])
7777
assert.Equal(t, msg, string(data[5:size]))
78-
assert.Equal(t, "E", string(data[0]))
79-
assert.Equal(t, 83, int(data[5]))
78+
// AuthenticationOk
79+
assert.Equal(t, uint8(0x52), data[0])
8080
}
8181

8282
func TestClose(t *testing.T) {
@@ -91,12 +91,12 @@ func TestClose(t *testing.T) {
9191
}
9292
}()
9393

94-
c := NewClient("tcp", "localhost:5432", 4096)
95-
assert.NotNil(t, c)
96-
c.Close()
97-
assert.Equal(t, "", c.ID)
98-
assert.Equal(t, "", c.Network)
99-
assert.Equal(t, "", c.Address)
100-
assert.Nil(t, c.Conn)
101-
assert.Equal(t, 0, c.ReceiveBufferSize)
94+
client := NewClient("tcp", "localhost:5432", DefaultBufferSize)
95+
assert.NotNil(t, client)
96+
client.Close()
97+
assert.Equal(t, "", client.ID)
98+
assert.Equal(t, "", client.Network)
99+
assert.Equal(t, "", client.Address)
100+
assert.Nil(t, client.Conn)
101+
assert.Equal(t, 0, client.ReceiveBufferSize)
102102
}

network/errors.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package network
2+
3+
import "errors"
4+
5+
var (
6+
ErrClientNotFound = errors.New("client not found")
7+
ErrNetworkNotSupported = errors.New("network is not supported")
8+
ErrClientNotConnected = errors.New("client is not connected")
9+
ErrPoolExhausted = errors.New("pool is exhausted")
10+
)

network/network_helpers_test.go

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,56 @@
11
package network
22

3-
import "encoding/binary"
3+
import (
4+
"encoding/binary"
5+
)
6+
7+
type WriteBuffer struct {
8+
Bytes []byte
9+
10+
msgStart int
11+
}
12+
13+
func writeStartupMsg(buf *WriteBuffer, user, database, appName string) {
14+
// Write startup message header
15+
buf.msgStart = len(buf.Bytes)
16+
buf.Bytes = append(buf.Bytes, 0, 0, 0, 0)
17+
18+
// Write protocol version
19+
buf.Bytes = append(buf.Bytes, 0, 0, 0, 0)
20+
binary.BigEndian.PutUint32(buf.Bytes[len(buf.Bytes)-4:], uint32(196608))
21+
22+
buf.WriteString("user")
23+
buf.WriteString(user)
24+
buf.WriteString("database")
25+
buf.WriteString(database)
26+
buf.WriteString("application_name")
27+
buf.WriteString(appName)
28+
buf.WriteString("")
29+
30+
// Write message length
31+
binary.BigEndian.PutUint32(
32+
buf.Bytes[buf.msgStart:], uint32(len(buf.Bytes)-buf.msgStart))
33+
}
34+
35+
func (buf *WriteBuffer) WriteString(s string) {
36+
buf.Bytes = append(buf.Bytes, s...)
37+
buf.Bytes = append(buf.Bytes, 0)
38+
}
439

540
func CreatePostgreSQLPacket(typ byte, msg []byte) []byte {
641
packet := make([]byte, 1+4+len(msg))
742

8-
packet = append(packet, typ)
9-
binary.BigEndian.PutUint32(packet, uint32(len(msg)+4))
10-
packet = append(packet, msg...)
43+
packet[0] = typ
44+
binary.BigEndian.PutUint32(packet[1:], uint32(len(msg)+4))
45+
for i, b := range msg {
46+
packet[i+5] = b
47+
}
1148

1249
return packet
1350
}
51+
52+
func CreatePgStartupPacket() []byte {
53+
buf := &WriteBuffer{}
54+
writeStartupMsg(buf, "postgres", "postgres", "gatewayd")
55+
return buf.Bytes
56+
}

0 commit comments

Comments
 (0)