Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add example tester service to show API Integration Testing of a Goa System #331

Merged
merged 52 commits into from
Jan 6, 2024
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
6f054d6
initial commit
jasondborneman Nov 21, 2023
023ece6
Empty-Commit
jasondborneman Nov 21, 2023
836488c
Merge pull request #1 from jasondborneman/initial
jasondborneman Nov 21, 2023
5d9f33c
add readme file (still need to fill out)
jasondborneman Nov 21, 2023
ced1c63
Merge pull request #2 from jasondborneman/initial
jasondborneman Nov 21, 2023
c0d8ebb
tester readme update
jasondborneman Nov 21, 2023
e7fe66e
Merge pull request #3 from jasondborneman/jdb/tester/readme
jasondborneman Nov 21, 2023
4e59ab6
Trying out a workflow to run integration tests against local binaries
jasondborneman Nov 21, 2023
9404ef6
Add proto install to /example/weather/scripts/setup
jasondborneman Nov 21, 2023
090cb8c
fix integration.yaml
jasondborneman Nov 21, 2023
4dd01db
disable mono on ubuntu
jasondborneman Nov 21, 2023
e822a6d
move mono stop
jasondborneman Nov 21, 2023
9883817
Try to find out what's running on 8084
jasondborneman Nov 21, 2023
a23d09d
Trying to disable mono?
jasondborneman Nov 21, 2023
9868199
trying to stop mono 2
jasondborneman Nov 21, 2023
f789909
add a sleep after stop/disable?
jasondborneman Nov 21, 2023
a87729c
add some echo
jasondborneman Nov 21, 2023
55a7c09
see if stop/disable mono fails
jasondborneman Nov 27, 2023
d6cb3da
add back in || true, change front ports to see if this even works at all
jasondborneman Nov 27, 2023
5f90a03
oops forgot to change int test port
jasondborneman Nov 27, 2023
e819d44
try no send to dev null?
jasondborneman Nov 27, 2023
83a9691
sleep before testing
jasondborneman Nov 27, 2023
54af7a6
take out netstat
jasondborneman Nov 27, 2023
c99addc
sleep longer? give time for docker to do work to get grafana?
jasondborneman Nov 27, 2023
072f246
remove dev>null again... :\
jasondborneman Nov 27, 2023
5e51620
sleep 60 :(
jasondborneman Nov 27, 2023
ad0ff0c
Implement review comment changes
jasondborneman Nov 27, 2023
0787db5
Merge pull request #5 from jasondborneman/jdb/tester/fixes112723
jasondborneman Nov 27, 2023
e1cd514
Fix runTests check for filtering if
jasondborneman Nov 27, 2023
2212857
Empty-Commit
jasondborneman Nov 27, 2023
3cebc13
Merge pull request #6 from jasondborneman/jdb/tester/fixes112723_2
jasondborneman Nov 27, 2023
7c7495a
Merge branch 'main' into jdb/tester/workflow
jasondborneman Nov 27, 2023
c439738
try starting each service individually, check fo rmono
jasondborneman Nov 27, 2023
c2dec1a
just KILL mono?
jasondborneman Nov 27, 2023
104c195
back to 8084, check all ports
jasondborneman Nov 27, 2023
89be0d0
fix typo
jasondborneman Nov 27, 2023
3817ebc
add flag to turn off grafana for services (for CI testing)
jasondborneman Nov 28, 2023
09062f1
clean up integration.yaml script
jasondborneman Nov 28, 2023
ad19923
Merge pull request #4 from jasondborneman/jdb/tester/workflow
jasondborneman Nov 28, 2023
eb0f830
review fixes
jasondborneman Nov 28, 2023
2bcd647
Merge pull request #7 from jasondborneman/jdb/tester/reviewfixes112823_1
jasondborneman Nov 28, 2023
591c3cb
Get Stack Trace to Err Log on Panic
jasondborneman Nov 29, 2023
fbddd73
Merge pull request #8 from jasondborneman/jdb/tester/errlogStackOnTes…
jasondborneman Nov 29, 2023
1a94d26
small fixes for style
jasondborneman Nov 30, 2023
715bd6e
Merge pull request #9 from jasondborneman/jdb/tester/smallfixes
jasondborneman Nov 30, 2023
5245d74
protoc -> 25.1, better wait in integration.yaml
jasondborneman Dec 4, 2023
eb6442f
Merge pull request #10 from jasondborneman/jdb/tester/workflow_fixes
jasondborneman Dec 4, 2023
ec3bc45
Add synchronous testing feature
jasondborneman Dec 5, 2023
ac71471
Make one of the synchronous as an example
jasondborneman Dec 5, 2023
adb3695
Merge pull request #11 from jasondborneman/jdb/tester/synchronoustests
jasondborneman Dec 5, 2023
d689bd6
Merge branch 'main' into merge-latest
jasondborneman Jan 5, 2024
78ca536
move func maps to service definition
jasondborneman Jan 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/integration.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Integration Tests

on:
workflow_dispatch:
push:
branches: [main]
pull_request:
types: [opened, reopened, synchronize]

jobs:
integration-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
go-version: "1.21"
- name: tests
run: |
echo "stop/disable/kill mono"
sudo systemctl stop mono-xsp4.service || true
sudo systemctl disable mono-xsp4.service || true
sudo pkill mono || true
echo "change to weather example directory"
cd example/weather
echo "run setup script"
./scripts/setup
echo "run server"
./bin/forecaster -monitoring-enabled=false &
./bin/locator -monitoring-enabled=false &
./bin/tester -monitoring-enabled=false &
./bin/front -monitoring-enabled=false &
sleep 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we couldn't instead wait for the service health checks to start responding? Using sleep really isn't great... Maybe we could introduct a function such as:

check_service_health() {
    local health_url="$1"
    local start_time=$(date +%s)

    while : ; do
        if curl -s --fail "$health_url" > /dev/null; then
            echo "Service is up!"
            return 0
        fi

        local current_time=$(date +%s)
        if (( current_time - start_time >= 5 )); then
            echo "Timed out waiting for service to be up."
            return 1
        fi

        sleep 0.2
    done
}

and then call it for each service concurrently and wait for the calls to return:

check_service_health "http://localhost:????/healthz" &
check_service_health "http://localhost:????/healthz" &
check_service_health "http://localhost:????/healthz" &
check_service_health "http://localhost:????/healthz" &
wait

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to tweak it a bit and add -n to the wait (otherwise it just hung) but this was a great suggestion, thanks!

echo "-----RUN TESTS-----"
results=$(curl -X POST http://localhost:8084/tester/smoke)
echo "-----RESULTS-----"
echo $results
echo "----------"
if [ $(echo $results | jq '.fail_count') -gt 0 ];
then
echo "Test errors found."
exit 1
else
echo "Tests passed."
exit 0
fi
11 changes: 11 additions & 0 deletions example/weather/scripts/setup
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,21 @@ source ./scripts/utils/common.sh

proto_pkg="protobuf-compiler"

# install protoc, update version as needed
PROTO_VER=24.4
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Latest version is 25.1 - it's a race! :)


if is_mac; then
PROTOC_ZIP=protoc-${PROTO_VER}-osx-universal_binary.zip
proto_pkg="protobuf"
else
PROTOC_ZIP=protoc-${PROTO_VER}-linux-x86_64.zip
fi

curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v${PROTO_VER}/${PROTOC_ZIP}
sudo unzip -o $PROTOC_ZIP -d /usr/local bin/protoc
sudo unzip -o $PROTOC_ZIP -d /usr/local 'include/*'
rm -f $PROTOC_ZIP

check_required_cmd "protoc" $proto_pkg

if [[ "$CI" == "" ]]; then
Expand Down
42 changes: 25 additions & 17 deletions example/weather/services/forecaster/cmd/forecaster/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ import (

func main() {
var (
grpcaddr = flag.String("grpc-addr", ":8080", "gRPC listen address")
httpaddr = flag.String("http-addr", ":8081", "HTTP listen address (health checks and metrics)")
agentaddr = flag.String("agent-addr", ":4317", "Grafana agent listen address")
debugf = flag.Bool("debug", false, "Enable debug logs")
grpcaddr = flag.String("grpc-addr", ":8080", "gRPC listen address")
httpaddr = flag.String("http-addr", ":8081", "HTTP listen address (health checks and metrics)")
agentaddr = flag.String("agent-addr", ":4317", "Grafana agent listen address")
debugf = flag.Bool("debug", false, "Enable debug logs")
monitoringEnabled = flag.Bool("monitoring-enabled", true, "monitoring")
)
flag.Parse()

Expand All @@ -51,19 +52,26 @@ func main() {
}

// 2. Setup tracing
log.Debugf(ctx, "connecting to Grafana agent %s", *agentaddr)
conn, err := grpc.DialContext(ctx, *agentaddr,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithBlock())
if err != nil {
log.Errorf(ctx, err, "failed to connect to Grafana agent")
os.Exit(1)
}
log.Debugf(ctx, "connected to Grafana agent %s", *agentaddr)
ctx, err = trace.Context(ctx, genforecaster.ServiceName, trace.WithGRPCExporter(conn))
if err != nil {
log.Errorf(ctx, err, "failed to initialize tracing")
os.Exit(1)
if !*monitoringEnabled {
var err error
if ctx, err = trace.Context(ctx, genforecaster.ServiceName, trace.WithDisabled()); err != nil {
log.Error(ctx, err, log.KV{K: "msg", V: "failed to initialize tracing"})
}
} else {
log.Debugf(ctx, "connecting to Grafana agent %s", *agentaddr)
conn, err := grpc.DialContext(ctx, *agentaddr,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithBlock())
if err != nil {
log.Errorf(ctx, err, "failed to connect to Grafana agent")
os.Exit(1)
}
log.Debugf(ctx, "connected to Grafana agent %s", *agentaddr)
ctx, err = trace.Context(ctx, genforecaster.ServiceName, trace.WithGRPCExporter(conn))
if err != nil {
log.Errorf(ctx, err, "failed to initialize tracing")
os.Exit(1)
}
}

// 3. Setup metrics
Expand Down
38 changes: 23 additions & 15 deletions example/weather/services/front/cmd/front/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ func main() {
locatorHealthAddr = flag.String("locator-health-addr", ":8083", "Locator service health-check address")
testerAddr = flag.String("tester-addr", ":8090", "Tester service address")
// No testerHealthAddr because we don't want the whole system to die just because tester isn't healthy for some reason
agentaddr = flag.String("agent-addr", ":4317", "Grafana agent listen address")
debugf = flag.Bool("debug", false, "Enable debug logs")
agentaddr = flag.String("agent-addr", ":4317", "Grafana agent listen address")
debugf = flag.Bool("debug", false, "Enable debug logs")
monitoringEnabled = flag.Bool("monitoring-enabled", true, "monitoring")
)
flag.Parse()

Expand All @@ -57,19 +58,26 @@ func main() {
}

// 2. Setup tracing
log.Debugf(ctx, "connecting to Grafana agent %s", *agentaddr)
conn, err := grpc.DialContext(ctx, *agentaddr,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithBlock())
if err != nil {
log.Errorf(ctx, err, "failed to connect to Grafana agent")
os.Exit(1)
}
log.Debugf(ctx, "connected to Grafana agent %s", *agentaddr)
ctx, err = trace.Context(ctx, genfront.ServiceName, trace.WithGRPCExporter(conn))
if err != nil {
log.Errorf(ctx, err, "failed to initialize tracing")
os.Exit(1)
if !*monitoringEnabled {
var err error
if ctx, err = trace.Context(ctx, genfront.ServiceName, trace.WithDisabled()); err != nil {
log.Error(ctx, err, log.KV{K: "msg", V: "failed to initialize tracing"})
}
} else {
log.Debugf(ctx, "connecting to Grafana agent %s", *agentaddr)
conn, err := grpc.DialContext(ctx, *agentaddr,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithBlock())
if err != nil {
log.Errorf(ctx, err, "failed to connect to Grafana agent")
os.Exit(1)
}
log.Debugf(ctx, "connected to Grafana agent %s", *agentaddr)
ctx, err = trace.Context(ctx, genfront.ServiceName, trace.WithGRPCExporter(conn))
if err != nil {
log.Errorf(ctx, err, "failed to initialize tracing")
os.Exit(1)
}
}

// 3. Setup metrics
Expand Down
42 changes: 25 additions & 17 deletions example/weather/services/locator/cmd/locator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ import (

func main() {
var (
grpcaddr = flag.String("grpc-addr", ":8082", "gRPC listen address")
httpaddr = flag.String("http-addr", ":8083", "HTTP listen address (health checks and metrics)")
agentaddr = flag.String("agent-addr", ":4317", "Grafana agent listen address")
debugf = flag.Bool("debug", false, "Enable debug logs")
grpcaddr = flag.String("grpc-addr", ":8082", "gRPC listen address")
httpaddr = flag.String("http-addr", ":8083", "HTTP listen address (health checks and metrics)")
agentaddr = flag.String("agent-addr", ":4317", "Grafana agent listen address")
debugf = flag.Bool("debug", false, "Enable debug logs")
monitoringEnabled = flag.Bool("monitoring-enabled", true, "monitoring")
)
flag.Parse()

Expand All @@ -51,19 +52,26 @@ func main() {
}

// 2. Setup tracing
log.Debugf(ctx, "connecting to Grafana agent %s", *agentaddr)
conn, err := grpc.DialContext(ctx, *agentaddr,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithBlock())
if err != nil {
log.Errorf(ctx, err, "failed to connect to Grafana agent")
os.Exit(1)
}
log.Debugf(ctx, "connected to Grafana agent %s", *agentaddr)
ctx, err = trace.Context(ctx, genlocator.ServiceName, trace.WithGRPCExporter(conn))
if err != nil {
log.Errorf(ctx, err, "failed to initialize tracing")
os.Exit(1)
if !*monitoringEnabled {
var err error
if ctx, err = trace.Context(ctx, genlocator.ServiceName, trace.WithDisabled()); err != nil {
log.Error(ctx, err, log.KV{K: "msg", V: "failed to initialize tracing"})
}
} else {
log.Debugf(ctx, "connecting to Grafana agent %s", *agentaddr)
conn, err := grpc.DialContext(ctx, *agentaddr,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithBlock())
if err != nil {
log.Errorf(ctx, err, "failed to connect to Grafana agent")
os.Exit(1)
}
log.Debugf(ctx, "connected to Grafana agent %s", *agentaddr)
ctx, err = trace.Context(ctx, genlocator.ServiceName, trace.WithGRPCExporter(conn))
if err != nil {
log.Errorf(ctx, err, "failed to initialize tracing")
os.Exit(1)
}
}

// 3. Setup metrics
Expand Down
34 changes: 21 additions & 13 deletions example/weather/services/tester/cmd/tester/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func main() {
locatorAddr = flag.String("locator-addr", ":8082", "Locator service address")
locatorHealthAddr = flag.String("locator-health-addr", ":8083", "Locator service health-check address")
debugf = flag.Bool("debug", false, "Enable debug logs")
monitoringEnabled = flag.Bool("monitoring-enabled", true, "monitoring")
)
flag.Parse()

Expand All @@ -56,19 +57,26 @@ func main() {
}

// 2. Setup tracing
log.Debugf(ctx, "connecting to Grafana agent %s", *agentaddr)
conn, err := grpc.DialContext(ctx, *agentaddr,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithBlock())
if err != nil {
log.Errorf(ctx, err, "failed to connect to Grafana agent")
os.Exit(1)
}
log.Debugf(ctx, "connected to Grafana agent %s", *agentaddr)
ctx, err = trace.Context(ctx, gentester.ServiceName, trace.WithGRPCExporter(conn))
if err != nil {
log.Errorf(ctx, err, "failed to initialize tracing")
os.Exit(1)
if !*monitoringEnabled {
var err error
if ctx, err = trace.Context(ctx, gentester.ServiceName, trace.WithDisabled()); err != nil {
log.Error(ctx, err, log.KV{K: "msg", V: "failed to initialize tracing"})
}
} else {
log.Debugf(ctx, "connecting to Grafana agent %s", *agentaddr)
conn, err := grpc.DialContext(ctx, *agentaddr,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithBlock())
if err != nil {
log.Errorf(ctx, err, "failed to connect to Grafana agent")
os.Exit(1)
}
log.Debugf(ctx, "connected to Grafana agent %s", *agentaddr)
ctx, err = trace.Context(ctx, gentester.ServiceName, trace.WithGRPCExporter(conn))
if err != nil {
log.Errorf(ctx, err, "failed to initialize tracing")
os.Exit(1)
}
}

// 3. Setup metrics
Expand Down