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

perf-test-initial-commit #139

Merged
merged 1 commit into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 21 additions & 0 deletions perf-tests/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Set destination for COPY


# Download Go modules
FROM golang:1.18-alpine
WORKDIR /app

WORKDIR /app

COPY go.mod ./
COPY go.sum ./
RUN go mod download
COPY *.go ./
COPY server.crt /app/server.crt
COPY server.key /app/server.key

RUN go build -o /enclave-server

EXPOSE 8082

CMD [ "/enclave-server" ]
45 changes: 45 additions & 0 deletions perf-tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
## What is in this folder?

We have done several runs to evaluate performace of enclaver/nitro-enclaves. As part of these tests I have created a simple GO server that works using a self signed SSL certificate and does a naive crypto operation.

API used to test - https://localhost:8082/hello

## Instance Setup

1. Provision a new nitro instance and follow the steps here to setup up nitro_allocator.yaml file https://edgebit.io/enclaver/docs/0.x/guide-first/

2. Modify the file `/etc/nitro_enclaves/allocator.yaml` to `cpu_count: 4`

3. Restart the nitro-allocator service using `sudo systemctl restart nitro-enclaves-allocator.service`

## JMeter setup

SSH into your machine and run the following commands

```
mkdir jmeter
cd jmeter
wget https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-5.5.tgz
tar -xf apache-jmeter-5.5.tgz
sudo amazon-linux-extras install java-openjdk11
```

## Running the tests

The script `./run_in_enclave.sh` contains the commands to start the nitro enclave.

Comment out the 4vcpu part of the script if you are using 2cvpu to start enclaves and vice-versa.

1. Start the enclave using the command `./run_in_enclave.sh`
2. Run JMeter tests using `./run_jmeter_test.sh`


## Sample results

With 4vCPUs -
`summary = 12000 in 00:00:42 = 283.7/s Avg: 155 Min: 12 Max: 2707 Err: 0 (0.00%)`

With 2vCPUs - `summary = 12000 in 00:00:41 = 290.3/s Avg: 108 Min: 14 Max: 1755 Err: 0 (0.00%)`

As you can see there is no significant difference in TPS by increasing the number of vCPUs.

90 changes: 90 additions & 0 deletions perf-tests/Test Plan.jmx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.5">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
<stringProp name="TestPlan.comments"></stringProp>
<boolProp name="TestPlan.functional_mode">false</boolProp>
<boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="TestPlan.user_define_classpath"></stringProp>
</TestPlan>
<hashTree>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
<boolProp name="LoopController.continue_forever">false</boolProp>
<stringProp name="LoopController.loops">1</stringProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">12000</stringProp>
<stringProp name="ThreadGroup.ramp_time">20</stringProp>
<boolProp name="ThreadGroup.scheduler">false</boolProp>
<stringProp name="ThreadGroup.duration">0</stringProp>
<stringProp name="ThreadGroup.delay">0</stringProp>
<boolProp name="ThreadGroup.same_user_on_next_iteration">false</boolProp>
</ThreadGroup>
<hashTree>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="HTTP Request" enabled="true">
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="HTTPSampler.domain">localhost</stringProp>
<stringProp name="HTTPSampler.port">8082</stringProp>
<stringProp name="HTTPSampler.protocol">https</stringProp>
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
<!-- <stringProp name="HTTPSampler.path">/abc/versions/xyz/encrypt/helloFormOUtised</stringProp> -->
<stringProp name="HTTPSampler.path">/hello</stringProp>
<stringProp name="HTTPSampler.method">GET</stringProp>
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
<stringProp name="HTTPSampler.implementation">HttpClient4</stringProp>
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
<stringProp name="HTTPSampler.response_timeout"></stringProp>
</HTTPSamplerProxy>
<hashTree/>
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>true</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>true</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>true</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>false</responseDataOnError>
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
<sentBytes>true</sentBytes>
<url>true</url>
<threadCounts>true</threadCounts>
<idleTime>true</idleTime>
<connectTime>true</connectTime>
</value>
</objProp>
<stringProp name="filename"></stringProp>
</ResultCollector>
<hashTree/>
</hashTree>
</hashTree>
</hashTree>
</jmeterTestPlan>
13 changes: 13 additions & 0 deletions perf-tests/enclaver_2vcpu.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: v1
name: "2vcpu"
target: "enclave_image_2vcpu"
sources:
app: "docker-go"
defaults:
memory_mb: 3000
cpu_count: 2
egress:
allow:
- "**"
ingress:
- listen_port: 8082
13 changes: 13 additions & 0 deletions perf-tests/enclaver_4vcpu.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: v1
name: "4vcpu"
target: "enclave_image_4vcpu"
sources:
app: "docker-go"
defaults:
memory_mb: 3000
cpu_count: 4
egress:
allow:
- "**"
ingress:
- listen_port: 8082
3 changes: 3 additions & 0 deletions perf-tests/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module main

go 1.20
44 changes: 44 additions & 0 deletions perf-tests/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M=
github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k=
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
16 changes: 16 additions & 0 deletions perf-tests/run_in_enclave.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# To run enclave with 2vCPU

# docker stop nitro_enclave
# docker rmi --force docker-go enclave_image_2vcpu
# docker build -t docker-go .
# enclaver build -f enclaver_2vcpu.yaml
# docker run -d --rm --name nitro_enclave --device=/dev/nitro_enclaves:/dev/nitro_enclaves:rw -p 8082:8082 enclave_image_2vcpu


# To run enclave with 4vCPU

docker stop nitro_enclave
docker rmi --force docker-go enclave_image_4vcpu
docker build -t docker-go .
enclaver build -f enclaver_4vcpu.yaml
docker run -d --rm --name nitro_enclave --device=/dev/nitro_enclaves:/dev/nitro_enclaves:rw -p 8082:8082 enclave_image_4vcpu
3 changes: 3 additions & 0 deletions perf-tests/run_jmeter_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cd ~/jmeter/apache-jmeter-5.5/bin/
results=$(./jmeter -n -t ~/go-app-enclave/Test\ Plan.jmx | grep "summary =")
echo -e "$results\n"
9 changes: 9 additions & 0 deletions perf-tests/server.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-----BEGIN CERTIFICATE-----
MIIBRTCBzQIJALQjjqycSdqWMAoGCCqGSM49BAMCMA0xCzAJBgNVBAYTAlVTMB4X
DTIzMDcxMDIxMDIwNloXDTMzMDcwNzIxMDIwNlowDTELMAkGA1UEBhMCVVMwdjAQ
BgcqhkjOPQIBBgUrgQQAIgNiAAQ2+qjs3MqQaWLBHQ7WEoS3jlapANuBGu6eggZj
2e+BOFGxg7fjADCB9bXt/t8glNkDTfqk34SdpkLkC1Hl3W1x311iHeXkRm8Qnrht
yOYGl1fB5GariDkgShJN7jGrDbMwCgYIKoZIzj0EAwIDZwAwZAIwafxlnHGKsyHH
QT9j4128glGBCGELt4aElm3aESOBH0lcix8RxTLHDCiqXFsLlZsOAjAzDwXyKyB+
e7npf54i1lXkIQB5Q/QfHO3fOQz5XHcg/50BrYbDirhrzpLT0aj1dKE=
-----END CERTIFICATE-----
60 changes: 60 additions & 0 deletions perf-tests/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package main

import (
// "fmt"
// "io"
"net/http"
"log"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"fmt"
)

var bytes = []byte{35, 46, 57, 24, 85, 35, 24, 74, 87, 35, 88, 98, 66, 32, 14, 05}
// This should be in an env file in production
const MySecret string = "abc&1*~#^2^#s0^=)^^7%b34"
func Encode(b []byte) string {
return base64.StdEncoding.EncodeToString(b)
}

func Encrypt(text, MySecret string) (string, error) {
block, err := aes.NewCipher([]byte(MySecret))
if err != nil {
return "", err
}
plainText := []byte(text)
cfb := cipher.NewCFBEncrypter(block, bytes)
cipherText := make([]byte, len(plainText))
cfb.XORKeyStream(cipherText, plainText)
return Encode(cipherText), nil
}

func HelloServer(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte("This is an example server.\n"))
StringToEncrypt := "Encrypting this string"
certificates := req.TLS.PeerCertificates
if len(certificates) > 0 {
fmt.Println("Found client certificate")
}

// To encrypt the StringToEncrypt
encText, err := Encrypt(StringToEncrypt, MySecret)
if err != nil {
fmt.Println("error encrypting your classified text: ", err)
}
// fmt.Println(encText)
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte(encText))
// fmt.Fprintf(w, "This is an example server.\n")
// io.WriteString(w, "This is an example server.\n")
}

func main() {
http.HandleFunc("/hello", HelloServer)
err := http.ListenAndServeTLS(":8082", "/app/server.crt", "/app/server.key", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
9 changes: 9 additions & 0 deletions perf-tests/server.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-----BEGIN EC PARAMETERS-----
BgUrgQQAIg==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MIGkAgEBBDAwGdtMVFJyVNoA8RO7WKXX7gQPplsBHUmMk6nDflKF/FBjQHpItcSm
pjMII3Hxg6ygBwYFK4EEACKhZANiAAQ2+qjs3MqQaWLBHQ7WEoS3jlapANuBGu6e
ggZj2e+BOFGxg7fjADCB9bXt/t8glNkDTfqk34SdpkLkC1Hl3W1x311iHeXkRm8Q
nrhtyOYGl1fB5GariDkgShJN7jGrDbM=
-----END EC PRIVATE KEY-----