Skip to content
This repository has been archived by the owner on Sep 1, 2024. It is now read-only.

Commit

Permalink
Merge branch 'portal-fixes' into latest_experiments_fix
Browse files Browse the repository at this point in the history
  • Loading branch information
ohadkoren committed Mar 28, 2024
2 parents d9f2840 + 1f39893 commit 95d95d5
Show file tree
Hide file tree
Showing 15 changed files with 92 additions and 56 deletions.
15 changes: 10 additions & 5 deletions ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
# Vision - Why Qujata?
We have identified that while there are [several performance test](https://github.com/open-quantum-safe/profiling) tools of PQ algorithms, we don't have much knowledge on what will happen to our live applications in real-world scenarios when integrating with PQ algorithms.
We would like to provide additional insights to the community, in the form of full-stack performance testing with different networking scenarios.

# Project Roadmap
Our benchmarking tool aims to understand, evaluate, and prepare for the integration of post-quantum cryptographic (PQC) algorithms in real-world scenarios. As we progress, our roadmap is designed to deepen our understanding, enhance our tools, learn from the community and gather valuable insights together.

### Phase 1: Full Stack Benchmarking Tool for TLS
* Functional Path: Develop a comprehensive benchmarking tool that evaluates the performance of post-quantum cryptographic algorithms within the context of a full TLS handshake. This will provide a holistic view of how these algorithms influence real-world applications.
* Architectural Path: The tool will be implemented using a modular microservices-based architecture, deployed on Kubernetes. It will integrate the OQS forks of Nginx and Curl, orchestrated by an Admin API and UI. Monitoring will be facilitated through Prometheus and Grafana, while metrics and logs are exposed via cAdvisor and kube-state-metrics. 
* Architectural Path: The tool will be implemented using a modular microservices-based architecture, deployed on Kubernetes. It will integrate the OQS forks of Nginx and Curl, orchestrated by an Admin API and UI. Monitoring will be facilitated through Prometheus and Grafana, while metrics and logs are exposed via cAdvisor and kube-state-metrics.
![image](https://github.com/att/qujata/assets/142991359/0aea246c-0927-436c-b02a-fccae03a6685)
### Phase 2: Real-world Scenario Testing
* Functional Path: Extend the tool to emulate real-world application scenarios, replicating standard user behaviors and interactions over secure channels. This involves introducing traffic patterns, application-specific interactions, and multi-session simulations.
* Architectural Path: Incorporate components simulate diverse user behaviors and generate traffic patterns. Integrate a Pod operator mechanism to preemptively manage and spin up new pods based on user input or anticipated demand.
![image](https://github.com/att/qujata/assets/142991359/cd1fbd28-c878-45c4-aa89-0979c9bad374)
### Phase 3: Benchmarking Non-TLS Protocols
* Functional Path: Expand the tool's capabilities to also benchmark popular non-TLS protocols integrating PQC, such as SSH, VPNs, and secure file transfers.
* Architectural Path: Introduce protocol-specific plugins or extensions to the benchmarking tool, ensuring flexible and accurate metrics collection for each protocol.
![image](https://github.com/att/qujata/assets/142991359/afe98ca3-8dfb-43d0-8807-8a361590d912)
### Continuous Enhancements
* Functional Path: Consistently update the tool to accommodate the latest PQC algorithms and stay aligned with evolving standards.
* Architectural Path: Adopt a plug-and-play model to seamlessly integrate new algorithms or protocols into the benchmarking tool. Ensure the platform remains cloud-agnostic, facilitating deployments on any major cloud service or on-premises.
* Analysis and Refinement: Regularly analyze the collected metrics, refining tools based on insights, and re-evaluating the significance of certain metrics to ensure the tool's continued relevance and accuracy.
### Community Engagement and Open Data
Our ultimate goal is not just internal knowledge but to provide the community with valuable insights. We plan to make our findings public, engage with the community for feedback, and open-source our tools for collaborative enhancement.

# Architecture
### Moving from our working prototype (phase 0) to phase 1

![image](https://github.com/att/qujata/assets/142991359/0b37cac3-0ba9-43e4-9c73-469efbb457a7)
# Current Architecture - Phase #1
![image](https://github.com/att/qujata/assets/142991359/960cd179-5b71-4309-a601-fdc8ae826778)

1 change: 1 addition & 0 deletions portal/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ case ${1} in
;;
esac

chmod -R 755 /usr/share/nginx/html/qujata
nginx -g 'daemon off;'
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const data = [
];
describe('BarChart', () => {
test('renders BarChart component', () => {
const { getByTestId }: RenderResult = render(<BarChart labels={['Algorithm1', 'Algorithm1']} data={data} title={'chart'} keyOfData={'average_cpu'} tooltipKeys={tooltipKeys} tooltipLabels={tooltipLabels} />);
const { getByTestId }: RenderResult = render(<BarChart labels={['Algorithm1', 'Algorithm1']} data={data} titleX='chartX' titleY='chartY' keyOfData={'average_cpu'} tooltipKeys={tooltipKeys} tooltipLabels={tooltipLabels} />);
const chartElement: HTMLElement = getByTestId('chart');
expect(chartElement).toBeTruthy();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ export interface BarChartProps {
keyOfData: string;
tooltipKeys: string[];
tooltipLabels: string[];
title?: string;
titleX?: string;
titleY?: string;
xAxiosTitle?: string;
}

export const BarChart: React.FC<BarChartProps> = (props: BarChartProps) => {
const { labels, data, tooltipKeys, tooltipLabels, keyOfData, title, xAxiosTitle } = props;
const { labels, data, tooltipKeys, tooltipLabels, keyOfData, titleX, titleY, xAxiosTitle } = props;
const [dataValues, setDataValues] = useState();
const [datasets, setDatasets] = useState<IDatasets[]>([]);
const [algorithmsColors, setAlgorithmsColors] = useState<{[key: string]: string}>();
Expand Down Expand Up @@ -55,7 +56,18 @@ export const BarChart: React.FC<BarChartProps> = (props: BarChartProps) => {
display: true,
title: {
display: true,
text: title ? title.replace(TITLE_PREFIX, '').trim() : '',
text: titleX ? titleX.replace(TITLE_PREFIX, '').trim() : '',
padding: { bottom: 30, top: 10 },
},
ticks: {
display: false,
},
},
y: {
display: true,
title: {
display: true,
text: titleY ? titleY.replace(TITLE_PREFIX, '').trim() : '',
padding: { bottom: 30, top: 10 },
},
ticks: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,3 @@
import { ChartOptions } from 'chart.js';
import { CHARTS_EN } from '../../../../home/components/experiment/components/charts/translate/en';

export const colors: string[] = ['#05BBFF', '#086CE1', '#FF8500', '#36a2eb33'];

export let defaultOptions: ChartOptions<any> = {
responsive: true,
aspectRatio: 2,
scales: {
y: {
title: {
display: true,
text: CHARTS_EN.Y_AXIS_TITLE,
font: {
size: 14,
},
padding: { bottom: 10 },
},
beginAtZero: true,
ticks: {
stepSize: 2,
font: {
size: 14,
},
},
},
},
};

export const TITLE_PREFIX = 'Server Memory (%) vs.';
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const mockData = {

describe('LineChart', () => {
test('renders LineChart', () => {
const { getByTestId }: RenderResult = render(<LineChart data={mockData} title='title' tooltipLabel='average_cpu' />);
const { getByTestId }: RenderResult = render(<LineChart data={mockData} titleX='chartX' titleY='chartY' tooltipLabel='average_cpu' />);
const chartElement: HTMLElement = getByTestId('line2');
expect(chartElement).toBeTruthy();
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,44 @@
import { Line } from 'react-chartjs-2';
import { ChartOptions, Chart, TooltipItem } from 'chart.js';
import { TITLE_PREFIX, defaultOptions } from './LineChart.const';
import { TITLE_PREFIX } from './LineChart.const';
import { useRef } from 'react';

export interface LineChartProps {
data: any;
tooltipLabel?: string;
title?: string;
titleX?: string;
titleY?: string;
xAxiosTitle?: string;
}

export const LineChart: React.FC<LineChartProps> = (props: LineChartProps) => {
const { data, title, tooltipLabel, xAxiosTitle } = props;
const { data, titleX, titleY, tooltipLabel, xAxiosTitle } = props;
const chartRef = useRef<Chart<"line", number[], unknown>>(null);

const options: ChartOptions<any> = {
...defaultOptions,
responsive: true,
aspectRatio: 2,
scales: {
...defaultOptions.scales,
x: {
display: true,
title: {
display: true,
text: title ? title.replace(TITLE_PREFIX, '').trim() : '',
text: titleX ? titleX.replace(TITLE_PREFIX, '').trim() : '',
},
},
y: {
display: true,
title: {
display: true,
text: titleY ? titleY.replace(TITLE_PREFIX, '').trim() : '',
padding: { bottom: 10 },
},
beginAtZero: true,
ticks: {
stepSize: 2,
font: {
size: 14,
},
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('DynamicChart', () => {
}],
});

const { container } = render(<BarChart title='Iterations' labels={[]} data={undefined} keyOfData={''} tooltipKeys={[]} tooltipLabels={[]} />);
const { container } = render(<BarChart titleX='Iterations' titleY='Bytes Throughput' labels={[]} data={undefined} keyOfData={''} tooltipKeys={[]} tooltipLabels={[]} />);
expect(container).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { CustomDropdownIndicator } from "./components/custom-dropdown-indicator"
import { BarChart } from "../../../../../../../dashboard/components/charts/BarChart";
import { useChartsData } from "../../hooks/useChartsData";
import { tooltipKeys, tooltipLabels } from "../../models/bar-chart.const";
import { getTitleByXAxiosValue } from "./utils/dynamic-chart.utils";
import { getTitleByXAxiosValue, getTitleByYAxiosValue } from "./utils/dynamic-chart.utils";
import { LineChart } from "../../../../../../../dashboard/components/charts/LineChart";
import { getChartTitleByType } from "../../utils/chart.utils";

Expand Down Expand Up @@ -104,8 +104,8 @@ export const DynamicChart: React.FC<DynamicChartProps> = (props: DynamicChartPro

{xAxisValue?.value && chartType?.value && yAxisValue?.value &&
<>
{chartType?.value === ChartType.BAR && barChartData && <BarChart title={getTitleByXAxiosValue(xAxisValue.value)} labels={barChartLabels} data={barChartData} tooltipKeys={tooltipKeys} tooltipLabels={tooltipLabels} keyOfData={yAxisValue.value} />}
{chartType?.value === ChartType.LINE && lineChartConvertData && <LineChart data={lineChartConvertData} title={getTitleByXAxiosValue(xAxisValue.value)} tooltipLabel={getChartTitleByType(yAxisValue.value)} />}
{chartType?.value === ChartType.BAR && barChartData && <BarChart titleX={getTitleByXAxiosValue(xAxisValue.value)} titleY={getTitleByYAxiosValue(yAxisValue.value)} labels={barChartLabels} data={barChartData} tooltipKeys={tooltipKeys} tooltipLabels={tooltipLabels} keyOfData={yAxisValue.value} />}
{chartType?.value === ChartType.LINE && lineChartConvertData && <LineChart data={lineChartConvertData} titleX={getTitleByXAxiosValue(xAxisValue.value)} titleY={getTitleByYAxiosValue(yAxisValue.value)} tooltipLabel={getChartTitleByType(yAxisValue.value)} />}
</>
}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ export enum XAxisType {
NUMBER_OF_ITERATIONS = 'Number of Iterations',
}

export enum YAxisType {
AVERAGE_CPU = 'Average CPU',
AVERAGE_MEMORY = 'Average Memory',
BYTES_THROUGHPUT = 'Bytes Throughput',
REQUEST_THROUGHPUT = 'Request Throughput',
}

export const xAxisTypeOptions: AttSelectOption[] = Object.keys(XAxisType).map((key) => ({
value: key,
label: XAxisType[key as keyof typeof XAxisType],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,11 @@ export const DYNAMIC_CHART_EN = {
},
X_VALUES_TITLE: {
ITERATIONS: 'Iterations',
},
Y_VALUES_TITLE: {
AVERAGE_CPU: 'Average CPU',
AVERAGE_MEMORY: 'Average Memory',
BYTES_THROUGHPUT: 'Bytes Throughput',
REQUEST_THROUGHPUT: 'Request Throughput',
}
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ChartType } from "../models/dynamic-chart.interface";
import { ChartType } from '../models/dynamic-chart.interface';
import LineSvg from '../../../../../../../../../../../src/assets/images/line.svg';
import BarSvg from '../../../../../../../../../../../src/assets/images/bar.svg';
import { DYNAMIC_CHART_EN } from "../translate/en";
import { DYNAMIC_CHART_EN } from '../translate/en';

export function getIconByValue(value: ChartType): string {
return value === ChartType.LINE ? LineSvg : BarSvg;
Expand All @@ -14,3 +14,18 @@ export function capitalizeFirstLetter(str: string): string {
export function getTitleByXAxiosValue(value: string): string {
return value === 'NUMBER_OF_ITERATIONS' ? DYNAMIC_CHART_EN.X_VALUES_TITLE.ITERATIONS : '';
}

export function getTitleByYAxiosValue(value: string): string {
switch (value) {
case 'average_cpu':
return DYNAMIC_CHART_EN.Y_VALUES_TITLE.AVERAGE_CPU;
case 'average_memory':
return DYNAMIC_CHART_EN.Y_VALUES_TITLE.AVERAGE_MEMORY;
case 'bytes_throughput':
return DYNAMIC_CHART_EN.Y_VALUES_TITLE.BYTES_THROUGHPUT;
case 'request_throughput':
return DYNAMIC_CHART_EN.Y_VALUES_TITLE.REQUEST_THROUGHPUT;
default:
return '';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ export const EXPERIMENT_TABLE_EN = {
HASHTAG: '#',
ALGORITHM: 'Algorithm',
ITERATIONS: 'Iterations',
MESSAGE_SIZE: 'Message Size (KB)',
AVERAGE_CPU: 'Average CPU',
AVERAGE_MEMORY: 'Average Memory',
THROUGHPUT_BYTES: 'Throughput (bytes/sec)',
THROUGHPUT_REQUEST: 'Throughput (message/sec)',
MESSAGE_SIZE: 'Message Size (Bytes)',
AVERAGE_CPU: 'Average CPU (Cores %)',
AVERAGE_MEMORY: 'Average Memory (MB)',
THROUGHPUT_BYTES: 'Throughput (Bytes/sec)',
THROUGHPUT_REQUEST: 'Throughput (Messages/sec)',
},
}
1 change: 1 addition & 0 deletions run/kubernetes/charts/api/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ env:
LOG_LEVEL: INFO
ENVIRONMENT: kubernetes
CURL_URL: http://qujata-curl:3010
CADVISOR_URL: http://qujata-cadvisor:8080
PROMETHEUS_URL: http://qujata-prometheus:9090
ITERATIONS_OPTIONS: 100:500:1000:2000:5000:10000:50000
MESSAGE_SIZES_OPTIONS: 0:1:2:100:1024:102400:204800:1048576:2097152:10485760
Expand Down
4 changes: 2 additions & 2 deletions run/kubernetes/charts/portal/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ securityContext: {}
# runAsNonRoot: true
# runAsUser: 1000
env:
PQC_PORTAL__DASHBOARD_LINK_HOST: http://localhost:3000/grafana
PQC_PORTAL__BASE_API_URL: http://localhost:3020/qujata-api
PQC_PORTAL__DASHBOARD_LINK_HOST: http://qujata-grafana:3000/grafana
PQC_PORTAL__BASE_API_URL: http://qujata-api:3020/qujata-api



Expand Down

0 comments on commit 95d95d5

Please sign in to comment.