mirror of https://github.com/ivanch/tcc.git
Compare commits
No commits in common. "2085b7d89bec1a4d6c6561961f9a43bcefe94458" and "81abfe0c30f4d8a239ed40cb8bbd09d0eebeba8c" have entirely different histories.
2085b7d89b
...
81abfe0c30
|
@ -4,6 +4,4 @@ bin
|
||||||
obj
|
obj
|
||||||
|
|
||||||
*.png
|
*.png
|
||||||
*.csv
|
*.csv
|
||||||
*.jpg
|
|
||||||
*.mp4
|
|
|
@ -34,13 +34,25 @@ namespace TCC.Controllers
|
||||||
[HttpGet("load-image")]
|
[HttpGet("load-image")]
|
||||||
public async Task<IActionResult> GetSimpleImage()
|
public async Task<IActionResult> GetSimpleImage()
|
||||||
{
|
{
|
||||||
return File(ImageService.GetSimpleImage(), "image/png");
|
var result = ImageService.GetSimpleImage();
|
||||||
|
|
||||||
|
var imageStream = new MemoryStream();
|
||||||
|
result.Write(imageStream);
|
||||||
|
imageStream.Position = 0;
|
||||||
|
|
||||||
|
return File(imageStream, "image/png");
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("load-big-image")]
|
[HttpGet("load-big-image")]
|
||||||
public async Task<IActionResult> GetBigImage()
|
public async Task<IActionResult> GetBigImage()
|
||||||
{
|
{
|
||||||
return File(ImageService.GetBigImage(), "image/png");
|
var result = ImageService.GetBigImage();
|
||||||
|
|
||||||
|
var imageStream = new MemoryStream();
|
||||||
|
result.Write(imageStream);
|
||||||
|
imageStream.Position = 0;
|
||||||
|
|
||||||
|
return File(imageStream, "image/png");
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("save-big-image")]
|
[HttpPost("save-big-image")]
|
||||||
|
|
|
@ -2,7 +2,6 @@ FROM mcr.microsoft.com/dotnet/sdk:6.0-bullseye-slim AS build-env
|
||||||
WORKDIR /App
|
WORKDIR /App
|
||||||
|
|
||||||
# Copy everything
|
# Copy everything
|
||||||
RUN apt update && apt install wget -y
|
|
||||||
COPY * .
|
COPY * .
|
||||||
|
|
||||||
# Restore as distinct layers
|
# Restore as distinct layers
|
||||||
|
@ -11,21 +10,16 @@ RUN dotnet restore
|
||||||
# Build a release
|
# Build a release
|
||||||
RUN dotnet build -c Release -o out
|
RUN dotnet build -c Release -o out
|
||||||
|
|
||||||
RUN cd out && \
|
|
||||||
wget https://files.ivanch.me/api/public/dl/QFCLgtrG/simpleimage.png && \
|
|
||||||
wget https://files.ivanch.me/api/public/dl/E0VLgWbx/bigimage.png && \
|
|
||||||
wget https://files.ivanch.me/api/public/dl/nTAYqZwD/video.mp4 && \
|
|
||||||
rm -rf runtimes && \
|
|
||||||
mkdir -p ./static && \
|
|
||||||
cp simpleimage.png ./static && \
|
|
||||||
cp bigimage.png ./static && \
|
|
||||||
mv video.mp4 ./static
|
|
||||||
|
|
||||||
# Build runtime image
|
# Build runtime image
|
||||||
FROM mcr.microsoft.com/dotnet/aspnet:6.0-bullseye-slim
|
FROM mcr.microsoft.com/dotnet/aspnet:6.0-bullseye-slim
|
||||||
|
|
||||||
WORKDIR /App
|
WORKDIR /App
|
||||||
|
|
||||||
|
RUN apt update && apt install wget -y && \
|
||||||
|
wget https://files.ivanch.me/api/public/dl/QFCLgtrG/simpleimage.png && \
|
||||||
|
wget https://files.ivanch.me/api/public/dl/E0VLgWbx/bigimage.png && \
|
||||||
|
rm -rf runtimes
|
||||||
|
|
||||||
COPY --from=build-env /App/out .
|
COPY --from=build-env /App/out .
|
||||||
|
|
||||||
ENTRYPOINT ["dotnet", "/App/TCC.APP.dll"]
|
ENTRYPOINT ["dotnet", "/App/TCC.APP.dll"]
|
|
@ -4,13 +4,13 @@ namespace tcc_app
|
||||||
{
|
{
|
||||||
public static class ImageHelper
|
public static class ImageHelper
|
||||||
{
|
{
|
||||||
public static byte[] SimpleImage;
|
public static MagickImage SimpleImage;
|
||||||
public static byte[] BigImage;
|
public static MagickImage BigImage;
|
||||||
|
|
||||||
static ImageHelper()
|
static ImageHelper()
|
||||||
{
|
{
|
||||||
SimpleImage = File.ReadAllBytes("static/simpleimage.png");
|
SimpleImage = new MagickImage("simpleimage.png");
|
||||||
BigImage = File.ReadAllBytes("static/bigimage.png");
|
BigImage = new MagickImage("bigimage.png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||||
using Microsoft.Extensions.FileProviders;
|
|
||||||
using TCC.Services;
|
using TCC.Services;
|
||||||
|
|
||||||
namespace TCC
|
namespace TCC
|
||||||
|
@ -19,13 +18,9 @@ namespace TCC
|
||||||
options.Limits.MaxRequestBodySize = int.MaxValue; // if don't set default value is: 30 MB
|
options.Limits.MaxRequestBodySize = int.MaxValue; // if don't set default value is: 30 MB
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
app.UseStaticFiles(new StaticFileOptions
|
|
||||||
{
|
|
||||||
FileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.ContentRootPath, "static")),
|
|
||||||
RequestPath = "/static"
|
|
||||||
});
|
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
"dotnetRunMessages": true,
|
"dotnetRunMessages": true,
|
||||||
"launchBrowser": false,
|
"launchBrowser": false,
|
||||||
"launchUrl": "weatherforecast",
|
"launchUrl": "weatherforecast",
|
||||||
"applicationUrl": "http://0.0.0.0:9090",
|
"applicationUrl": "http://0.0.0.0:5100",
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,12 +62,12 @@ namespace TCC.Services
|
||||||
file.Close();
|
file.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] GetSimpleImage()
|
public MagickImage GetSimpleImage()
|
||||||
{
|
{
|
||||||
return ImageHelper.SimpleImage;
|
return ImageHelper.SimpleImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] GetBigImage()
|
public MagickImage GetBigImage()
|
||||||
{
|
{
|
||||||
return ImageHelper.BigImage;
|
return ImageHelper.BigImage;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Welcome to nginx!</title>
|
|
||||||
<style>
|
|
||||||
html {
|
|
||||||
color-scheme: light dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
width: 35em;
|
|
||||||
margin: 0 auto;
|
|
||||||
font-family: Tahoma, Verdana, Arial, sans-serif;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Welcome to nginx!</h1>
|
|
||||||
<p>
|
|
||||||
If you see this page, the nginx web server is successfully installed and
|
|
||||||
working. Further configuration is required.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
For online documentation and support please refer to
|
|
||||||
<a href="http://nginx.org/">nginx.org</a>.<br />
|
|
||||||
Commercial support is available at
|
|
||||||
<a href="http://nginx.com/">nginx.com</a>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p><em>Thank you for using nginx.</em></p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -26,9 +26,8 @@ def getData(filename):
|
||||||
|
|
||||||
def generateGraph(filename, framework_name, endpoint_name):
|
def generateGraph(filename, framework_name, endpoint_name):
|
||||||
x, y = getData(filename)
|
x, y = getData(filename)
|
||||||
|
new_filename = ".".join(filename.split('.')[:-1])
|
||||||
new_filename = filename.replace('.txt', '').replace('.csv', '')
|
|
||||||
plot_graph(x, y, f'{framework_name} - {endpoint_name}', 'Number of requests', 'Requests per second', new_filename)
|
plot_graph(x, y, f'{framework_name} - {endpoint_name}', 'Number of requests', 'Requests per second', new_filename)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
generateGraph('data.txt', 'Teste', 'endpoint')
|
generateGraph('data.txt', 'ASP.NET', 'test')
|
||||||
|
|
|
@ -4,36 +4,30 @@ import time
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
from graph import generateGraph
|
from graph import generateGraph
|
||||||
from math import floor
|
|
||||||
|
|
||||||
if len(sys.argv) != 2 or sys.argv[1] == '-h' or sys.argv[1] == '--help':
|
if len(sys.argv) != 2 or sys.argv[1] == '-h' or sys.argv[1] == '--help':
|
||||||
print("Usage: python testes.py <name>")
|
print("Usage: python testes.py <name>")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
THREADS = 10
|
|
||||||
FRAMEWORK_NAME = sys.argv[1]
|
FRAMEWORK_NAME = sys.argv[1]
|
||||||
URL_BASE = 'http://172.26.48.1:9080'
|
URL_BASE = 'http://localhost:9080'
|
||||||
API_REQUESTS = [
|
ENDPOINTS = [
|
||||||
('/status/ok', range(0, 50_000, 5000)),
|
'/status/ok',
|
||||||
('/image/load-image', range(0, 50_000, 5000)),
|
'/image/load-image',
|
||||||
('/image/load-big-image', range(0, 1_000, 10)),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
#num_requests = [10, 1000, 5000, 10_000, 50_000, 100_000, 500_000, 1_000_000]
|
||||||
|
num_requests = range(0, 50_000, 5000)
|
||||||
|
|
||||||
def send_request(url):
|
def send_request(url):
|
||||||
success = False
|
success = False
|
||||||
responses = {
|
|
||||||
2: 0, # OK
|
|
||||||
4: 0, # Bad Request
|
|
||||||
5: 0, # Server Error
|
|
||||||
}
|
|
||||||
while not success:
|
while not success:
|
||||||
try:
|
try:
|
||||||
response = requests.get(url)
|
response = requests.get(url)
|
||||||
except:
|
except:
|
||||||
continue
|
continue
|
||||||
success = response.status_code == 200
|
success = response.status_code == 200
|
||||||
responses[floor(response.status_code/100)] += 1
|
return response.status_code
|
||||||
return responses
|
|
||||||
|
|
||||||
def getFileName(endpoint):
|
def getFileName(endpoint):
|
||||||
endpoint = endpoint.replace('/', '_')
|
endpoint = endpoint.replace('/', '_')
|
||||||
|
@ -43,7 +37,7 @@ def record(filename, requests, reqpersec):
|
||||||
with open(filename, "a") as file:
|
with open(filename, "a") as file:
|
||||||
file.write(f"{requests},{reqpersec}\n")
|
file.write(f"{requests},{reqpersec}\n")
|
||||||
|
|
||||||
def run_tests(endpoint, num_requests):
|
def run_tests(endpoint):
|
||||||
filename = getFileName(endpoint)
|
filename = getFileName(endpoint)
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
os.remove(filename)
|
os.remove(filename)
|
||||||
|
@ -51,11 +45,7 @@ def run_tests(endpoint, num_requests):
|
||||||
for num_request in num_requests:
|
for num_request in num_requests:
|
||||||
if num_request <= 0: continue
|
if num_request <= 0: continue
|
||||||
|
|
||||||
ok_responses = 0
|
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
|
||||||
bad_responses = 0
|
|
||||||
server_errors = 0
|
|
||||||
|
|
||||||
with concurrent.futures.ThreadPoolExecutor(max_workers=THREADS) as executor:
|
|
||||||
url = f'{URL_BASE}{endpoint}'
|
url = f'{URL_BASE}{endpoint}'
|
||||||
|
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
|
@ -69,18 +59,12 @@ def run_tests(endpoint, num_requests):
|
||||||
|
|
||||||
elapsed_time = time.time() - start_time
|
elapsed_time = time.time() - start_time
|
||||||
|
|
||||||
for future in futures:
|
print(f"{num_request}: {elapsed_time:.2f} seconds. {elapsed_time/num_request:.4f} seconds per request. {num_request/elapsed_time:.2f} requests per second.")
|
||||||
responses = future.result()
|
|
||||||
ok_responses += responses[2]
|
|
||||||
bad_responses += responses[4]
|
|
||||||
server_errors += responses[5]
|
|
||||||
|
|
||||||
print(f"{num_request}: {elapsed_time:.2f} seconds. {elapsed_time/num_request:.4f} seconds per request. {num_request/elapsed_time:.2f} requests per second. [OK: {ok_responses}, Bad Request: {bad_responses}, Server Error: {server_errors}]]")
|
|
||||||
record(filename, num_request, f"{num_request/elapsed_time:.2f}")
|
record(filename, num_request, f"{num_request/elapsed_time:.2f}")
|
||||||
generateGraph(filename, FRAMEWORK_NAME, endpoint)
|
generateGraph(filename, FRAMEWORK_NAME, endpoint)
|
||||||
|
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
|
|
||||||
for endpoint, num_requests in API_REQUESTS:
|
for endpoint in ENDPOINTS:
|
||||||
print(f"# {endpoint}")
|
print(f"# {endpoint}")
|
||||||
run_tests(endpoint, num_requests)
|
run_tests(endpoint)
|
||||||
|
|
Loading…
Reference in New Issue