Skip to content

Commit d4bd9b2

Browse files
committed
wip
1 parent ffa3412 commit d4bd9b2

File tree

13 files changed

+1429
-1
lines changed

13 files changed

+1429
-1
lines changed

src/integration/doc.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Package integration contains integration tests for Log Cache components.
2+
package integration

src/integration/gateway_test.go

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
package integration_test
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"io"
7+
"net/http"
8+
"os/exec"
9+
"time"
10+
11+
logcache "code.cloudfoundry.org/go-log-cache/v2/rpc/logcache_v1"
12+
"code.cloudfoundry.org/log-cache/integration/integrationfakes"
13+
. "github.com/onsi/ginkgo/v2"
14+
. "github.com/onsi/gomega"
15+
"github.com/onsi/gomega/gexec"
16+
)
17+
18+
var _ = Describe("Gateway", func() {
19+
var (
20+
fakeLogCache *integrationfakes.FakeLogCache
21+
22+
gatewayPort int
23+
gateway *gexec.Session
24+
)
25+
26+
BeforeEach(func() {
27+
port := 8000 + GinkgoParallelProcess()
28+
fakeLogCache = integrationfakes.NewFakeLogCache(port, nil)
29+
30+
gatewayPort = 8081 + GinkgoParallelProcess()
31+
})
32+
33+
JustBeforeEach(func() {
34+
fakeLogCache.Start()
35+
36+
envVars := map[string]string{
37+
"ADDR": fmt.Sprintf(":%d", gatewayPort),
38+
"LOG_CACHE_ADDR": fakeLogCache.Address(),
39+
"METRICS_PORT": "0",
40+
}
41+
command := exec.Command(componentPaths.Gateway)
42+
for k, v := range envVars {
43+
command.Env = append(command.Env, fmt.Sprintf("%s=%s", k, v))
44+
}
45+
var err error
46+
gateway, err = gexec.Start(command, GinkgoWriter, GinkgoWriter)
47+
Expect(err).ShouldNot(HaveOccurred())
48+
})
49+
50+
JustAfterEach(func() {
51+
gateway.Interrupt().Wait(2 * time.Second)
52+
fakeLogCache.Stop()
53+
})
54+
55+
Context("/api/v1/info endpoint", func() {
56+
var resp *http.Response
57+
58+
JustBeforeEach(func() {
59+
u := fmt.Sprintf("http://localhost:%d/api/v1/info", gatewayPort)
60+
Eventually(func() error {
61+
var err error
62+
resp, err = http.Get(u)
63+
return err
64+
}, "5s").ShouldNot(HaveOccurred())
65+
})
66+
67+
AfterEach(func() {
68+
resp.Body.Close()
69+
})
70+
71+
It("returns 200", func() {
72+
Expect(resp.StatusCode).To(Equal(http.StatusOK))
73+
})
74+
75+
PIt("returns Content-Type as application/json", func() {
76+
Expect(resp.Header.Get("Content-Type")).To(Equal("application/json"))
77+
})
78+
79+
PIt("returns Content-Length", func() {
80+
Expect(resp.Header.Get("Content-Length")).To(MatchRegexp("\\d+"))
81+
})
82+
83+
Context("response body", func() {
84+
var body []byte
85+
86+
JustBeforeEach(func() {
87+
var err error
88+
body, err = io.ReadAll(resp.Body)
89+
Expect(err).ToNot(HaveOccurred())
90+
})
91+
92+
It("is a JSON with version and uptime information", func() {
93+
result := struct {
94+
Version string `json:"version"`
95+
VMUptime string `json:"vm_uptime"`
96+
}{}
97+
err := json.Unmarshal(body, &result)
98+
Expect(err).ToNot(HaveOccurred())
99+
Expect(result.Version).To(Equal("1.2.3"))
100+
Expect(result.VMUptime).To(MatchRegexp("\\d+"))
101+
})
102+
103+
It("has a newline at the end", func() {
104+
Expect(string(body)).To(MatchRegexp(".*\\n$"))
105+
})
106+
})
107+
})
108+
109+
Context("api/v1/read endpoint", func() {
110+
var resp *http.Response
111+
112+
JustBeforeEach(func() {
113+
u := fmt.Sprintf("http://localhost:%d/api/v1/read", gatewayPort)
114+
Eventually(func() error {
115+
var err error
116+
resp, err = http.Get(u)
117+
return err
118+
}, "5s").ShouldNot(HaveOccurred())
119+
})
120+
121+
AfterEach(func() {
122+
resp.Body.Close()
123+
})
124+
125+
It("returns 200", func() {
126+
Expect(resp.StatusCode).To(Equal(http.StatusOK))
127+
})
128+
129+
PIt("returns Content-Type as application/json", func() {
130+
Expect(resp.Header.Get("Content-Type")).To(Equal("application/json"))
131+
})
132+
133+
PIt("returns Content-Length", func() {
134+
Expect(resp.Header.Get("Content-Length")).To(MatchRegexp("\\d+"))
135+
})
136+
137+
PIt("forwards the request to Log Cache", func() {
138+
// Expect(flc.requestCount).To(Equal(1))
139+
})
140+
141+
Context("response body", func() {
142+
var body []byte
143+
144+
JustBeforeEach(func() {
145+
var err error
146+
body, err = io.ReadAll(resp.Body)
147+
Expect(err).ToNot(HaveOccurred())
148+
})
149+
150+
PIt("is a JSON with envelopes", func() {
151+
var rr logcache.ReadResponse
152+
err := json.Unmarshal(body, &rr)
153+
Expect(err).ToNot(HaveOccurred())
154+
Expect(rr.Envelopes).To(HaveLen(0))
155+
})
156+
157+
It("has a newline at the end", func() {
158+
Expect(string(body)).To(MatchRegexp(".*\\n$"))
159+
})
160+
})
161+
})
162+
})
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package integration_test
2+
3+
import (
4+
"encoding/json"
5+
"testing"
6+
7+
. "github.com/onsi/ginkgo/v2"
8+
. "github.com/onsi/gomega"
9+
"github.com/onsi/gomega/gexec"
10+
)
11+
12+
type ComponentPaths struct {
13+
Gateway string `json:"gateway_path"`
14+
CFAuthProxy string `json:"cf_auth_proxy_path"`
15+
LogCache string `json:"log_cache_path"`
16+
SyslogServer string `json:"syslog_server_path"`
17+
}
18+
19+
var componentPaths ComponentPaths
20+
21+
func NewComponentPaths() ComponentPaths {
22+
cps := ComponentPaths{}
23+
24+
path, err := gexec.Build("code.cloudfoundry.org/log-cache/cmd/gateway", "-ldflags", "-X main.buildVersion=1.2.3")
25+
Expect(err).NotTo(HaveOccurred())
26+
cps.Gateway = path
27+
28+
path, err = gexec.Build("code.cloudfoundry.org/log-cache/cmd/cf-auth-proxy")
29+
Expect(err).NotTo(HaveOccurred())
30+
cps.CFAuthProxy = path
31+
32+
path, err = gexec.Build("code.cloudfoundry.org/log-cache/cmd/log-cache")
33+
Expect(err).NotTo(HaveOccurred())
34+
cps.LogCache = path
35+
36+
path, err = gexec.Build("code.cloudfoundry.org/log-cache/cmd/syslog-server")
37+
Expect(err).NotTo(HaveOccurred())
38+
cps.SyslogServer = path
39+
40+
return cps
41+
}
42+
43+
func (cps *ComponentPaths) Marshal() []byte {
44+
data, err := json.Marshal(cps)
45+
Expect(err).NotTo(HaveOccurred())
46+
return data
47+
}
48+
49+
func TestIntegration(t *testing.T) {
50+
RegisterFailHandler(Fail)
51+
RunSpecs(t, "Integration Suite")
52+
}
53+
54+
var _ = SynchronizedBeforeSuite(func() []byte {
55+
cps := NewComponentPaths()
56+
return cps.Marshal()
57+
}, func(data []byte) {
58+
Expect(json.Unmarshal(data, &componentPaths)).To(Succeed())
59+
})
60+
61+
var _ = SynchronizedAfterSuite(func() {}, func() {
62+
gexec.CleanupBuildArtifacts()
63+
})
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package integrationfakes
2+
3+
import (
4+
"context"
5+
"crypto/tls"
6+
"fmt"
7+
"net"
8+
9+
logcache "code.cloudfoundry.org/go-log-cache/v2/rpc/logcache_v1"
10+
"google.golang.org/grpc"
11+
"google.golang.org/grpc/credentials"
12+
)
13+
14+
type FakeLogCache struct {
15+
port int
16+
addr string
17+
c *tls.Config
18+
s *grpc.Server
19+
20+
serveCh chan error
21+
22+
logcache.UnimplementedEgressServer
23+
logcache.UnimplementedIngressServer
24+
logcache.UnimplementedPromQLQuerierServer
25+
}
26+
27+
func NewFakeLogCache(port int, c *tls.Config) *FakeLogCache {
28+
return &FakeLogCache{
29+
port: port,
30+
c: c,
31+
serveCh: make(chan error),
32+
}
33+
}
34+
35+
func (f *FakeLogCache) Start() error {
36+
lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", f.port))
37+
if err != nil {
38+
return err
39+
}
40+
f.addr = lis.Addr().String()
41+
42+
f.s = grpc.NewServer()
43+
if f.c != nil {
44+
f.s = grpc.NewServer(grpc.Creds(credentials.NewTLS(f.c)))
45+
}
46+
47+
logcache.RegisterEgressServer(f.s, f)
48+
logcache.RegisterIngressServer(f.s, f)
49+
logcache.RegisterPromQLQuerierServer(f.s, f)
50+
51+
go func() {
52+
f.serveCh <- f.s.Serve(lis)
53+
}()
54+
55+
return nil
56+
}
57+
58+
func (f *FakeLogCache) Address() string {
59+
return f.addr
60+
}
61+
62+
func (f *FakeLogCache) Read(ctx context.Context, req *logcache.ReadRequest) (*logcache.ReadResponse, error) {
63+
return nil, nil
64+
}
65+
66+
func (f *FakeLogCache) Stop() error {
67+
f.s.Stop()
68+
return <-f.serveCh
69+
}

src/internal/gateway/gateway.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,10 @@ func (g *Gateway) handleInfoEndpoint(w http.ResponseWriter, r *http.Request) {
186186
}
187187

188188
func uptimeInSeconds() int64 {
189-
hostStats, _ := host.Info()
189+
hostStats, err := host.Info()
190+
if err != nil {
191+
return 0
192+
}
190193
return int64(hostStats.Uptime)
191194
}
192195

0 commit comments

Comments
 (0)