Skip to content

Commit 203acf6

Browse files
feat: add http-sse and simple grpc application (#204)
* feat: add http-sse application Signed-off-by: Asish Kumar <[email protected]> * feat: implement a simple Go gRPC service with Keploy integration and test cases. Signed-off-by: Asish Kumar <[email protected]> * feat: Add simple-grpc and http-sse to the golangci-lint workflow's working directory matrix. * fix: lint Signed-off-by: Asish Kumar <[email protected]> * fix: lint Signed-off-by: Asish Kumar <[email protected]> * fix: lint Signed-off-by: Asish Kumar <[email protected]> * chore: add readme for simple-grpc Signed-off-by: Asish Kumar <[email protected]> --------- Signed-off-by: Asish Kumar <[email protected]>
1 parent faf4305 commit 203acf6

31 files changed

+2561
-0
lines changed

http-sse/Caddyfile.record

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
:80 {
2+
@sse_student path /subscribe/student/events*
3+
reverse_proxy @sse_student host.docker.internal:8047
4+
5+
@sse_teacher path /subscribe/teacher/events*
6+
reverse_proxy @sse_teacher host.docker.internal:8047
7+
8+
reverse_proxy host.docker.internal:8000
9+
}

http-sse/Caddyfile.replay

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
:80 {
2+
@sse_student path /subscribe/student/events*
3+
reverse_proxy @sse_student host.docker.internal:8000
4+
5+
@sse_teacher path /subscribe/teacher/events*
6+
reverse_proxy @sse_teacher host.docker.internal:8000
7+
8+
reverse_proxy host.docker.internal:8000
9+
}

http-sse/Readme.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
2+
# HTTP + SSE Sample with Keploy
3+
4+
This sample demonstrates how to test a Go application that serves both standard **HTTP** endpoints and **Server-Sent Events (SSE)** on different ports using [Keploy](https://keploy.io).
5+
6+
It uses **Caddy** as a reverse proxy to route traffic to the appropriate ports based on the request path.
7+
8+
## Prerequisites
9+
10+
- [Go](https://go.dev/doc/install) (1.21 or later)
11+
- [Docker](https://docs.docker.com/engine/install/) (for running Caddy)
12+
- [Keploy](https://keploy.io/docs/server/installation/)
13+
14+
## Architecture
15+
16+
- **HTTP Server**: Listens on port `8000`. Handles API requests.
17+
- **SSE Server**: Listens on port `8047`. Handles real-time event streams.
18+
- **Caddy (Router)**: Listens on port `80`. Routes `/subscribe/*` to port `8047` and everything else to `8000`.
19+
20+
## Setup
21+
22+
### 1. Start the Caddy Router
23+
Run the following command to start Caddy in a Docker container. This will simulate a production-like routing environment where a gateway handles traffic distribution.
24+
25+
```bash
26+
docker rm -f sse-router 2>/dev/null || true
27+
docker run --name sse-router --rm -p 80:80 \
28+
--add-host=host.docker.internal:host-gateway \
29+
-v "$PWD/Caddyfile.record:/etc/caddy/Caddyfile" \
30+
caddy:2-alpine
31+
```
32+
33+
## Recording Test Cases
34+
35+
Open a new terminal to run the application with Keploy recording enabled.
36+
37+
### 1. Start the Application
38+
```bash
39+
keploy record
40+
```
41+
42+
### 2. Generate Traffic
43+
Send requests to the Caddy router (localhost:80).
44+
45+
**Standard HTTP Request:**
46+
```bash
47+
# 1. Health Check
48+
curl -i "http://localhost:8000/health"
49+
50+
# 2. Simple Hello
51+
curl -i "http://localhost:8000/api/hello"
52+
53+
# 3. Echo (with message)
54+
curl -i "http://localhost:8000/api/echo?msg=Greetings"
55+
56+
# 3b. Echo (empty/default message)
57+
curl -i "http://localhost:8000/api/echo"
58+
59+
# 4. Add Numbers
60+
curl -i "http://localhost:8000/api/add?a=50&b=25"
61+
62+
# 5. Get Current Time
63+
curl -i "http://localhost:8000/api/time"
64+
65+
# 6. Get Resource by ID
66+
curl -i "http://localhost:8000/api/resource/user-123"
67+
```
68+
69+
**SSE Request (Student):**
70+
```bash
71+
curl -N -H "Accept: text/event-stream" \
72+
"http://localhost/subscribe/student/events?doubtId=abc"
73+
```
74+
75+
**SSE Request (Teacher):**
76+
```bash
77+
curl -N -H "Accept: text/event-stream" \
78+
"http://localhost/subscribe/teacher/events?teacherId=t-42"
79+
```
80+
81+
*Note: You can verify that traffic is being routed correctly by checking the "port" field in JSON responses or the server logs.*
82+
83+
## Running Tests
84+
85+
Once you have recorded the test cases, you can stop the recording (Ctrl+C) and run the tests.
86+
87+
```bash
88+
keploy test
89+
```
90+
91+
Keploy will replay the recorded traffic and verify that the responses match the expected output, ensuring that routing and logic remain consistent.

http-sse/go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module keploy-sse-port-repro
2+
3+
go 1.23.0

http-sse/keploy.yml

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Generated by Keploy (3-dev)
2+
path: ""
3+
appName: http-sse
4+
appId: 0
5+
command: go run main.go
6+
templatize:
7+
testSets: []
8+
port: 0
9+
e2e: false
10+
dnsPort: 26789
11+
proxyPort: 16789
12+
incomingProxyPort: 36789
13+
debug: false
14+
disableTele: false
15+
disableANSI: false
16+
containerName: ""
17+
networkName: ""
18+
buildDelay: 30
19+
test:
20+
selectedTests: {}
21+
globalNoise:
22+
global: {}
23+
test-sets: {}
24+
replaceWith:
25+
global:
26+
url:
27+
"localhost:8081": "localhost:8000"
28+
"doubt.local-2": "localhost:8047"
29+
test-sets:
30+
http:
31+
url:
32+
"localhost:8003": "localhost:8000"
33+
"localhost:8004": "localhost:8000"
34+
sse:
35+
url:
36+
"doubt.local": "localhost:8047"
37+
delay: 5
38+
host: ""
39+
port: 0
40+
grpcPort: 0
41+
apiTimeout: 5
42+
skipCoverage: false
43+
coverageReportPath: ""
44+
ignoreOrdering: true
45+
mongoPassword: default@123
46+
language: ""
47+
removeUnusedMocks: false
48+
fallBackOnMiss: false
49+
jacocoAgentPath: ""
50+
basePath: ""
51+
mocking: true
52+
ignoredTests: {}
53+
disableLineCoverage: false
54+
disableMockUpload: true
55+
useLocalMock: false
56+
updateTemplate: false
57+
mustPass: false
58+
maxFailAttempts: 5
59+
maxFlakyChecks: 1
60+
protoFile: ""
61+
protoDir: ""
62+
protoInclude: []
63+
compareAll: false
64+
schemaMatch: false
65+
record:
66+
filters: []
67+
basePath: ""
68+
recordTimer: 0s
69+
metadata: ""
70+
sync: false
71+
globalPassthrough: false
72+
tlsPrivateKeyPath: ""
73+
report:
74+
selectedTestSets: {}
75+
showFullBody: false
76+
reportPath: ""
77+
summary: false
78+
testCaseIDs: []
79+
disableMapping: true
80+
configPath: ""
81+
bypassRules: []
82+
generateGithubActions: false
83+
keployContainer: keploy-v3
84+
keployNetwork: keploy-network
85+
cmdType: native
86+
contract:
87+
services: []
88+
tests: []
89+
path: ""
90+
download: false
91+
generate: false
92+
driven: consumer
93+
mappings:
94+
servicesMapping: {}
95+
self: s1
96+
inCi: false
97+
serverPort: 0
98+
mockDownload:
99+
registryIds: []
100+
101+
# Visit [https://keploy.io/docs/running-keploy/configuration-file/] to learn about using keploy through configration file.

http-sse/keploy/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
/reports/
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Generated by Keploy (3-dev)
2+
version: api.keploy.io/v1beta1
3+
kind: Http
4+
name: test-1
5+
spec:
6+
metadata: {}
7+
req:
8+
method: GET
9+
proto_major: 1
10+
proto_minor: 1
11+
url: http://localhost:8001/health
12+
header:
13+
Accept: '*/*'
14+
Host: localhost:8000
15+
User-Agent: curl/8.5.0
16+
body: ""
17+
timestamp: 2026-02-17T06:34:38.563350239Z
18+
resp:
19+
status_code: 200
20+
header:
21+
Content-Length: "24"
22+
Content-Type: application/json
23+
Date: Tue, 17 Feb 2026 06:34:38 GMT
24+
body: |
25+
{"ok":true,"port":8000}
26+
status_message: OK
27+
proto_major: 0
28+
proto_minor: 0
29+
timestamp: 2026-02-17T06:34:38.564104851Z
30+
objects: []
31+
assertions:
32+
noise:
33+
header.Date: []
34+
created: 1771310078
35+
app_port: 8010
36+
curl: |
37+
curl --request GET \
38+
--url http://localhost:8000/health \
39+
--header 'Host: localhost:8000' \
40+
--header 'User-Agent: curl/8.5.0' \
41+
--header 'Accept: */*' \
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Generated by Keploy (3-dev)
2+
version: api.keploy.io/v1beta1
3+
kind: Http
4+
name: test-2
5+
spec:
6+
metadata: {}
7+
req:
8+
method: GET
9+
proto_major: 1
10+
proto_minor: 1
11+
url: http://localhost:8002/api/hello
12+
header:
13+
Accept: '*/*'
14+
Host: localhost:8000
15+
User-Agent: curl/8.5.0
16+
body: ""
17+
timestamp: 2026-02-17T06:34:38.569422851Z
18+
resp:
19+
status_code: 200
20+
header:
21+
Content-Length: "38"
22+
Content-Type: application/json
23+
Date: Tue, 17 Feb 2026 06:34:38 GMT
24+
body: |
25+
{"msg":"hello from http","port":8000}
26+
status_message: OK
27+
proto_major: 0
28+
proto_minor: 0
29+
timestamp: 2026-02-17T06:34:38.569685606Z
30+
objects: []
31+
assertions:
32+
noise:
33+
header.Date: []
34+
created: 1771310078
35+
app_port: 8010
36+
curl: |
37+
curl --request GET \
38+
--url http://localhost:8000/api/hello \
39+
--header 'Accept: */*' \
40+
--header 'Host: localhost:8000' \
41+
--header 'User-Agent: curl/8.5.0' \
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Generated by Keploy (3-dev)
2+
version: api.keploy.io/v1beta1
3+
kind: Http
4+
name: test-3
5+
spec:
6+
metadata: {}
7+
req:
8+
method: GET
9+
proto_major: 1
10+
proto_minor: 1
11+
url: http://localhost:8002/api/echo?msg=Greetings
12+
url_params:
13+
msg: Greetings
14+
header:
15+
Accept: '*/*'
16+
Host: localhost:8000
17+
User-Agent: curl/8.5.0
18+
body: ""
19+
timestamp: 2026-02-17T06:34:38.5751624Z
20+
resp:
21+
status_code: 200
22+
header:
23+
Content-Length: "33"
24+
Content-Type: application/json
25+
Date: Tue, 17 Feb 2026 06:34:38 GMT
26+
body: |
27+
{"echo":"Greetings","port":8000}
28+
status_message: OK
29+
proto_major: 0
30+
proto_minor: 0
31+
timestamp: 2026-02-17T06:34:38.575379672Z
32+
objects: []
33+
assertions:
34+
noise:
35+
header.Date: []
36+
created: 1771310078
37+
app_port: 8010
38+
curl: |
39+
curl --request GET \
40+
--url http://localhost:8000/api/echo?msg=Greetings \
41+
--header 'User-Agent: curl/8.5.0' \
42+
--header 'Accept: */*' \
43+
--header 'Host: localhost:8000' \
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Generated by Keploy (3-dev)
2+
version: api.keploy.io/v1beta1
3+
kind: Http
4+
name: test-4
5+
spec:
6+
metadata: {}
7+
req:
8+
method: GET
9+
proto_major: 1
10+
proto_minor: 1
11+
url: http://localhost:8000/api/echo
12+
header:
13+
Accept: '*/*'
14+
Host: localhost:8000
15+
User-Agent: curl/8.5.0
16+
body: ""
17+
timestamp: 2026-02-17T06:34:38.579242321Z
18+
resp:
19+
status_code: 200
20+
header:
21+
Content-Length: "29"
22+
Content-Type: application/json
23+
Date: Tue, 17 Feb 2026 06:34:38 GMT
24+
body: |
25+
{"echo":"empty","port":8000}
26+
status_message: OK
27+
proto_major: 0
28+
proto_minor: 0
29+
timestamp: 2026-02-17T06:34:38.579479596Z
30+
objects: []
31+
assertions:
32+
noise:
33+
header.Date: []
34+
created: 1771310078
35+
app_port: 8010
36+
curl: |
37+
curl --request GET \
38+
--url http://localhost:8000/api/echo \
39+
--header 'Accept: */*' \
40+
--header 'Host: localhost:8000' \
41+
--header 'User-Agent: curl/8.5.0' \

0 commit comments

Comments
 (0)