Skip to content

Commit

Permalink
Xray performance test (#330)
Browse files Browse the repository at this point in the history
* adding mock http server

* added testing to httpserver

* added graceful shutdown

* added check data

* added certificates for https

Co-authored-by: name <[email protected]>

* Merge main to traces-performance-test (#3)

* Upgrade EKS Version and Fix EKS EMF Log JSON (#329)

* Multi-System Trace Integration Test (#318)

Co-authored-by: Jeffrey Chien <[email protected]>

---------

Co-authored-by: Seth L <[email protected]>
Co-authored-by: Jeffrey Chien <[email protected]>

* added xray performance test

* generating traces

* PR Cleanup (#6)

* trying docker

* PR Cleanup

* alternative optional mock server start

* merging docker branch

* Restructed Xray Test

---------

Co-authored-by: name <[email protected]>
Co-authored-by: Seth L <[email protected]>
  • Loading branch information
3 people authored Oct 6, 2023
1 parent bca3359 commit 7c94832
Show file tree
Hide file tree
Showing 25 changed files with 678 additions and 40 deletions.
6 changes: 4 additions & 2 deletions generator/test_case_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ type matrixRow struct {
type testConfig struct {
// this gives more flexibility to define terraform dir when there should be a different set of terraform files
// e.g. statsd can have a multiple terraform module sets for difference test scenarios (ecs, eks or ec2)
testDir string
terraformDir string
testDir string
terraformDir string
runMockServer bool
// define target matrix field as set(s)
// empty map means a testConfig will be created with a test entry for each entry from *_test_matrix.json
targets map[string]map[string]struct{}
Expand Down Expand Up @@ -130,6 +131,7 @@ var testTypeToTestConfig = map[string][]testConfig{
{testDir: "../../test/performance/system"},
{testDir: "../../test/performance/statsd"},
{testDir: "../../test/performance/collectd"},
{testDir: "../../test/performance/trace/xray", runMockServer: true},
},
"ec2_windows_performance": {
{testDir: "../../test/performance/windows/logs"},
Expand Down
13 changes: 13 additions & 0 deletions mockserver/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM golang:1.19 AS build
WORKDIR $GOPATH/main
COPY . .
RUN go env -w GOPROXY=direct
RUN GO111MODULE=on go mod download
RUN GO111MODULE=on CGO_ENABLED=0 GOOS=linux go build -o=/bin/main .
EXPOSE 80
EXPOSE 443
FROM scratch
ENV AWS_REGION="us-west-2"
COPY --from=build /bin/main /bin/main
COPY certificates certificates
ENTRYPOINT ["/bin/main"]
26 changes: 26 additions & 0 deletions mockserver/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Header above mocked_servers cert in bundle
CERT_HEADER=mockserver

CONFIG_PATH=openssl.conf
CERT_PATH=certificates/ssl/certificate.crt
KEY_PATH=certificates/private.key
BUNDLE_PATH=certificates/ssl/ca-bundle.crt
.PHONY: clean
clean:
rm -rf $(CERT_PATH) $(BUNDLE_PATH) $(KEY_PATH)
touch $(CERT_PATH) $(BUNDLE_PATH) $(KEY_PATH)
.PHONY: update-certs
update-certs: clean gen-cert update-bundle

# Expects mocked_servers cert to be the last cert in the bundle
# Cuts until the first instance of "mocked_servers" in the bundle
# and concatenates it with the current cert
.PHONY: update-bundle
update-bundle:
sed /$(CERT_HEADER)/q $(BUNDLE_PATH) | cat - $(CERT_PATH) > $(BUNDLE_PATH).tmp && \
mv $(BUNDLE_PATH).tmp $(BUNDLE_PATH)

# Generates the annual cert and private key using the config
.PHONY: gen-cert
gen-cert:
openssl req -config $(CONFIG_PATH) -new -x509 -nodes -days 365 -out $(CERT_PATH) -keyout $(KEY_PATH)
41 changes: 41 additions & 0 deletions mockserver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# The Mock Server

## Overview

The Mock Server is a simple server designed for receiving metric and trace data, providing a simulated endpoint for testing purposes. It listens on two separate ports: 8080 and 443.
## Running the server
This server is runs as a docker container to run this server:
1. First build the docker container with
```sh
sudo docker build -t mockserver .
```
2. Run the container by mapping the ports you would like to use, for example:
```sh
sudo docker run --name mockserver -d -p 8080:8080 -p 443:443 mockserver
```

## How it Works
### The Receiver

The receiver component of the Mock Server operates on port 443. It is responsible for receiving messages and incrementing the transaction count. To simulate real-world conditions, there is a built-in 15ms latency between each received message. The data received can be sent to three possible routes:

- **Check Receiver Status:** You can check if the receiver is alive by making a request to `/ping`.

- **Send Data:** Use the `/put-data` route to send data. This route supports two sub-routes:
- `/put-data/trace/v1`: Use this sub-route for sending trace data.
- `/put-data/metrics`: Use this sub-route for sending metrics data.

> [!Important]
> Currently, both traces and metrics are handled in the same way.
### The Verifier

The verifier component can be accessed via a listener on port 8080. It provides information about the transactions, including:

- **Transactions per Minute:** You can obtain the transactions per minute by making a request to `/tpm`.

- **Transaction Count:** To check the total transaction count, use the `/check-data` route.

- **Verifier Status:** Determine if the verification server is alive by sending a request to `/ping`.


52 changes: 52 additions & 0 deletions mockserver/certificates/private.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
MS4NuDAuF8b/rhwtUJW4UY19lq3fstdV
-----END PRIVATE KEY-----
36 changes: 36 additions & 0 deletions mockserver/certificates/ssl/ca-bundle.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
-----BEGIN CERTIFICATE-----
MIIGOTCCBCGgAwIBAgIUTbGrEtezpQ4lTSJq4Vq4/Wf7wokwDQYJKoZIhvcNAQEL
BQAwgaAxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQH
DAdTZWF0dGxlMRgwFgYDVQQKDA9FeGFtcGxlIENvbXBhbnkxFjAUBgNVBAsMDUlU
IERlcGFydG1lbnQxIjAgBgkqhkiG9w0BCQEWE2V4YW1wbGVAZXhhbXBsZS5jb20x
FDASBgNVBAMMC2V4YW1wbGUuY29tMB4XDTIzMDgxNjIzMDY0M1oXDTI0MDgxNTIz
MDY0M1owgaAxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYD
VQQHDAdTZWF0dGxlMRgwFgYDVQQKDA9FeGFtcGxlIENvbXBhbnkxFjAUBgNVBAsM
DUlUIERlcGFydG1lbnQxIjAgBgkqhkiG9w0BCQEWE2V4YW1wbGVAZXhhbXBsZS5j
b20xFDASBgNVBAMMC2V4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
MIICCgKCAgEArNKLtT2UkXx5i1JpFiN7qXJ1Elo0HKFFzUnksT5+bELRHjm3fdQ/
MQVQDhU3UxYCr+ayk+zXA6X5Vv/2/6LzqrotbsSgwIptSx7OGroTL0V4YtoixTgq
5QBbg1zhXjXtsb3f8wya+KUDWI4ni20hoV0CoTT+hOIoLgrkmS4VfGqo+epZOX4v
ToogCM9iai6b+Rdx9WBhXXuf5b+cMrhb6M2E3oSBfCg6XLr5dzVm9++kDoIVfT5Z
m+EKC2DduE755Tha4Kaycts0Sp9W2dYzqyLIge9NMBx3BVpZMm9JPqNQaA1hWjdZ
QQ59e9aEqeRTVwf/OsLCSll/24ub/Rx809dijKT7Nxxb3Wz0nZlIkYVcF/VzaW79
LJuiaN2V9ha7Vo+6VjwPe1R67JwrRK7XW96pwChchxrXuIAgQwukc2P0sedfvixP
p8iLpGsGN2CMl5/J/nuQClDOsOyvbE8S49u5JAcO9UdQysB6BIaBTshNim0Iuk/9
mMTkHJb3wvagvDNbEDMODnV2pCTZ+hJY7tjzI2I/HyzzsKYTZ/u8+qfH41ir76xp
H4CHxKUivGOxJvzLak/kR9e5E/AGayZ5pS0YMhECGlGejxG52pCWUtcxjwT+7p87
GOgWfY81F3TILRBCUoJvnN7z4QlLf+9FVuaQWTvvj80gUJJGk5QmWOcCAwEAAaNp
MGcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBaAwLgYDVR0RBCcwJYIJbG9jYWxob3N0
ggkxMjcuMC4wLjGCDW1vY2tlZC1zZXJ2ZXIwHQYDVR0OBBYEFK0KPMa2jkCkjtQI
35yprUPDT+XcMA0GCSqGSIb3DQEBCwUAA4ICAQBCqvGkeBmklslKPUQtfLD6h2uJ
7l/CsVn9Vw8c6SMIwL83IjUHyFxSmQauplYOKH6wN5++EUYazPYXfQRrbNXa9dMw
U8W7B8neo2/EVF3GC+9lGEhhiGgBIizwID9CG1k6vl40TPmD7o4qNP8QjQeAQbDo
bRta2oCb+40IOVHJQrr3H3KzP+6sRd4H3WbyWAf/Wtb76GSC4M52xmcL99SsaK0u
q1jErAGekfc6l37KHUypimaA065KgnJz7Crg1t6JUNHjpROXjdkrf1+TZZ/z6C+p
KPm2zvITUvr05dLlS05J2ghOd3B/+DDg0b+GgOuqq3bxcTgNwVPogpKO/mJGIxY/
HDPkLcPulnaHm+NB/IIK2owfnXRC8Qujq2bthyHdP4cGGn4Q82cA8FRO04L3oGrC
6BcroCZqWkllaVNJtoFig0UqXQv6aNqT0kgO3B12Km7wd50ye2+awyVP62J0Bi9W
qBNMWT5LVAgt6sY4xBwxjKd3fizoQEcxRrD2Hk+mw4DCU/6ni5PSf8l0x31Mk5rk
UnuHFMnxTBBfUonIhRKg59b5qVdgs6Il8N+aRV2ZP3WUoOEZCFiNzqbJrcjMMlur
8Zj/fYYyywA7Ck4Srv8NPVskc4wic1aXBlDvbz4UjC+T1ElIfgM36HfV+d/weMs/
rKvn+B6q4wmPGcC4Rw==
-----END CERTIFICATE-----
36 changes: 36 additions & 0 deletions mockserver/certificates/ssl/certificate.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
-----BEGIN CERTIFICATE-----
MIIGOTCCBCGgAwIBAgIUTbGrEtezpQ4lTSJq4Vq4/Wf7wokwDQYJKoZIhvcNAQEL
BQAwgaAxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQH
DAdTZWF0dGxlMRgwFgYDVQQKDA9FeGFtcGxlIENvbXBhbnkxFjAUBgNVBAsMDUlU
IERlcGFydG1lbnQxIjAgBgkqhkiG9w0BCQEWE2V4YW1wbGVAZXhhbXBsZS5jb20x
FDASBgNVBAMMC2V4YW1wbGUuY29tMB4XDTIzMDgxNjIzMDY0M1oXDTI0MDgxNTIz
MDY0M1owgaAxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYD
VQQHDAdTZWF0dGxlMRgwFgYDVQQKDA9FeGFtcGxlIENvbXBhbnkxFjAUBgNVBAsM
DUlUIERlcGFydG1lbnQxIjAgBgkqhkiG9w0BCQEWE2V4YW1wbGVAZXhhbXBsZS5j
b20xFDASBgNVBAMMC2V4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
MIICCgKCAgEArNKLtT2UkXx5i1JpFiN7qXJ1Elo0HKFFzUnksT5+bELRHjm3fdQ/
MQVQDhU3UxYCr+ayk+zXA6X5Vv/2/6LzqrotbsSgwIptSx7OGroTL0V4YtoixTgq
5QBbg1zhXjXtsb3f8wya+KUDWI4ni20hoV0CoTT+hOIoLgrkmS4VfGqo+epZOX4v
ToogCM9iai6b+Rdx9WBhXXuf5b+cMrhb6M2E3oSBfCg6XLr5dzVm9++kDoIVfT5Z
m+EKC2DduE755Tha4Kaycts0Sp9W2dYzqyLIge9NMBx3BVpZMm9JPqNQaA1hWjdZ
QQ59e9aEqeRTVwf/OsLCSll/24ub/Rx809dijKT7Nxxb3Wz0nZlIkYVcF/VzaW79
LJuiaN2V9ha7Vo+6VjwPe1R67JwrRK7XW96pwChchxrXuIAgQwukc2P0sedfvixP
p8iLpGsGN2CMl5/J/nuQClDOsOyvbE8S49u5JAcO9UdQysB6BIaBTshNim0Iuk/9
mMTkHJb3wvagvDNbEDMODnV2pCTZ+hJY7tjzI2I/HyzzsKYTZ/u8+qfH41ir76xp
H4CHxKUivGOxJvzLak/kR9e5E/AGayZ5pS0YMhECGlGejxG52pCWUtcxjwT+7p87
GOgWfY81F3TILRBCUoJvnN7z4QlLf+9FVuaQWTvvj80gUJJGk5QmWOcCAwEAAaNp
MGcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBaAwLgYDVR0RBCcwJYIJbG9jYWxob3N0
ggkxMjcuMC4wLjGCDW1vY2tlZC1zZXJ2ZXIwHQYDVR0OBBYEFK0KPMa2jkCkjtQI
35yprUPDT+XcMA0GCSqGSIb3DQEBCwUAA4ICAQBCqvGkeBmklslKPUQtfLD6h2uJ
7l/CsVn9Vw8c6SMIwL83IjUHyFxSmQauplYOKH6wN5++EUYazPYXfQRrbNXa9dMw
U8W7B8neo2/EVF3GC+9lGEhhiGgBIizwID9CG1k6vl40TPmD7o4qNP8QjQeAQbDo
bRta2oCb+40IOVHJQrr3H3KzP+6sRd4H3WbyWAf/Wtb76GSC4M52xmcL99SsaK0u
q1jErAGekfc6l37KHUypimaA065KgnJz7Crg1t6JUNHjpROXjdkrf1+TZZ/z6C+p
KPm2zvITUvr05dLlS05J2ghOd3B/+DDg0b+GgOuqq3bxcTgNwVPogpKO/mJGIxY/
HDPkLcPulnaHm+NB/IIK2owfnXRC8Qujq2bthyHdP4cGGn4Q82cA8FRO04L3oGrC
6BcroCZqWkllaVNJtoFig0UqXQv6aNqT0kgO3B12Km7wd50ye2+awyVP62J0Bi9W
qBNMWT5LVAgt6sY4xBwxjKd3fizoQEcxRrD2Hk+mw4DCU/6ni5PSf8l0x31Mk5rk
UnuHFMnxTBBfUonIhRKg59b5qVdgs6Il8N+aRV2ZP3WUoOEZCFiNzqbJrcjMMlur
8Zj/fYYyywA7Ck4Srv8NPVskc4wic1aXBlDvbz4UjC+T1ElIfgM36HfV+d/weMs/
rKvn+B6q4wmPGcC4Rw==
-----END CERTIFICATE-----
5 changes: 5 additions & 0 deletions mockserver/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module mockserver

go 1.20

require github.com/gorilla/mux v1.8.0
1 change: 1 addition & 0 deletions mockserver/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
140 changes: 140 additions & 0 deletions mockserver/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// Copyright 2023 Amazon.com, Inc. or its affiliates
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"context"
"encoding/json"
"io"
"log"
"net/http"
"path"
"sync"
"sync/atomic"
"time"

"github.com/gorilla/mux"
)

const (
HealthCheckMessage = "healthcheck"
SuccessMessage = "success"
)

var (
CertFilePath = path.Join("certificates", "ssl", "certificate.crt")
KeyFilePath = path.Join("certificates", "private.key")
)

type transactionHttpServer struct {
transactions uint32
startTime time.Time
}

type TransactionPayload struct {
TransactionsPerMinute float64 `json:"GetNumberOfTransactionsPerMinute"`
}

func healthCheck(w http.ResponseWriter, _ *http.Request) {
if _, err := io.WriteString(w, HealthCheckMessage); err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Printf("Unable to write response: %v", err)
return
}
w.WriteHeader(http.StatusOK)
}

func (ts *transactionHttpServer) checkTransactionCount(w http.ResponseWriter, _ *http.Request) {
var message string
var t = atomic.LoadUint32(&ts.transactions)
if t > 0 {
message = SuccessMessage
}
log.Printf("\033[31m Time: %d | checkTransactionCount msg: %s | %d\033[0m \n", time.Now().Unix(), message, t)
if _, err := io.WriteString(w, message); err != nil {
w.WriteHeader(http.StatusInternalServerError)
io.WriteString(w, err.Error())
log.Printf("Unable to write response: %v", err)
return
}
w.WriteHeader(http.StatusOK)
}

func (ts *transactionHttpServer) recordTransaction(w http.ResponseWriter, _ *http.Request) {
atomic.AddUint32(&ts.transactions, 1)

// Built-in latency
log.Printf("\033[31m Time: %s | transaction received \033[0m \n", time.Now().String())
time.Sleep(15 * time.Millisecond)
w.WriteHeader(http.StatusOK)
}

// Retrieve number of transactions per minute
func (ts *transactionHttpServer) GetNumberOfTransactionsPerMinute(w http.ResponseWriter, _ *http.Request) {
// Calculate duration in minutes
duration := time.Now().Sub(ts.startTime)
transactions := float64(atomic.LoadUint32(&ts.transactions))
tpm := transactions / duration.Minutes()

w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(TransactionPayload{tpm}); err != nil {
w.WriteHeader(http.StatusInternalServerError)
io.WriteString(w, err.Error())
log.Printf("Unable to write response: %v", err)
}
}

// Starts an HTTP server that receives request from validator only to verify the data ingestion
func StartHttpServer() {
var wg sync.WaitGroup
log.Println("\033[31m Starting Server \033[0m")
store := transactionHttpServer{startTime: time.Now()}
//2 servers one for receiving the data , one for verify data
dataApp := mux.NewRouter()
dataReceiverServer := &http.Server{Addr: ":443", Handler: dataApp}
verificationRequestServer := http.NewServeMux()
appServer := &http.Server{Addr: ":8080", Handler: verificationRequestServer}
wg.Add(2)
go func(ts *transactionHttpServer) {
defer wg.Done()
dataApp.HandleFunc("/ping", healthCheck)
dataApp.PathPrefix("/put-data").HandlerFunc(ts.recordTransaction)
dataApp.HandleFunc("/trace/v1", ts.recordTransaction)
dataApp.HandleFunc("/metric/v1", ts.recordTransaction)
if err := dataReceiverServer.ListenAndServeTLS(CertFilePath, KeyFilePath); err != nil {
log.Printf("HTTPS server error: %v", err)
err = dataReceiverServer.Shutdown(context.TODO())
log.Fatalf("Shutdown server error: %v", err)
}
}(&store)

go func(ts *transactionHttpServer) {
defer wg.Done()
verificationRequestServer.HandleFunc("/ping", healthCheck)
verificationRequestServer.HandleFunc("/check-data", ts.checkTransactionCount)
verificationRequestServer.HandleFunc("/tpm", ts.GetNumberOfTransactionsPerMinute)
if err := appServer.ListenAndServe(); err != nil {
log.Printf("Verification server error: %v", err)
err := appServer.Shutdown(context.TODO())
log.Fatalf("Shutdown server error: %v", err)
}
}(&store)
wg.Wait()
log.Println("\033[32m Stopping Server \033[0m")
}

func main() {
StartHttpServer()
}
Loading

0 comments on commit 7c94832

Please sign in to comment.