Skip to content

Commit 79cd0fe

Browse files
authored
Merge branch 'main' into mapper-tool
2 parents 978ee89 + 29de4e1 commit 79cd0fe

File tree

18 files changed

+1298
-40
lines changed

18 files changed

+1298
-40
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: CI Knative Setup
2+
description: Sets up the CI environment with Kind, Serving, and Kourier for Knative platform type
3+
inputs:
4+
go-version:
5+
description: Version of Go to set up
6+
required: true
7+
default: '1.22'
8+
runs:
9+
using: "composite"
10+
steps:
11+
- name: Checkout repository
12+
uses: actions/checkout@v4
13+
with:
14+
lfs: "true"
15+
16+
- name: Checkout LFS objects
17+
shell: bash
18+
run: git lfs checkout
19+
20+
- name: Set up Go
21+
uses: actions/setup-go@v5
22+
with:
23+
go-version: ${{ inputs.go-version }}
24+
25+
- name: Create k8s Kind Cluster
26+
shell: bash
27+
run: bash ./scripts/konk-ci/01-kind.sh
28+
29+
- name: Install Serving
30+
shell: bash
31+
run: bash ./scripts/konk-ci/02-serving.sh
32+
33+
- name: Install Kourier
34+
shell: bash
35+
run: bash ./scripts/konk-ci/02-kourier.sh
36+
37+
- name: Setup domain and autoscaler
38+
shell: bash
39+
run: |
40+
INGRESS_HOST="127.0.0.1"
41+
KNATIVE_DOMAIN=$INGRESS_HOST.sslip.io
42+
kubectl patch configmap -n knative-serving config-domain -p "{\"data\": {\"$KNATIVE_DOMAIN\": \"\"}}"
43+
kubectl patch configmap -n knative-serving config-autoscaler -p "{\"data\": {\"allow-zero-initial-scale\": \"true\"}}"
44+
kubectl patch configmap -n knative-serving config-features -p "{\"data\": {\"kubernetes.podspec-affinity\": \"enabled\"}}"
45+
kubectl label node knative-control-plane loader-nodetype=worker

.github/configs/wordlist.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,3 +798,18 @@ AsyncMode
798798
AsyncResponseURL
799799
AsyncWaitToCollectMin
800800
Knative's
801+
BaseConfigPath
802+
LoaderStudy
803+
LoaderExperiment
804+
PostScript
805+
PreScript
806+
IatGeneration
807+
LoaderConfiguration
808+
PostScript
809+
PreScript
810+
TraceFormat
811+
TraceValues
812+
TracesDir
813+
TracesFormat
814+
baseLoaderConfig
815+
iats
Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
name: End-to-End Tests
1+
name: End-to-End Loader Test
22

33
on:
4-
schedule:
5-
- cron: "0 9 * * 1"
6-
workflow_dispatch:
7-
push:
8-
branches: [main]
9-
pull_request:
10-
branches: [main]
4+
schedule:
5+
- cron: "0 9 * * 1"
6+
workflow_dispatch:
7+
push:
8+
branches: [main]
9+
pull_request:
10+
branches: [main]
1111

1212
env:
1313
GOOS: linux
@@ -20,7 +20,6 @@ jobs:
2020
KIND_VERSION: v0.22.0
2121
K8S_VERSION: v1.29
2222
YAML_DIR: workloads/container
23-
2423
runs-on: ubuntu-20.04
2524
strategy:
2625
fail-fast: false
@@ -30,33 +29,11 @@ jobs:
3029
trace_func_go,
3130
]
3231
steps:
33-
- uses: actions/checkout@v4
34-
with:
35-
lfs: "true"
36-
- name: Checkout LFS objects
37-
run: git lfs checkout
38-
39-
- uses: actions/setup-go@v5
40-
with:
41-
go-version: 1.22
42-
43-
- name: Create k8s Kind Cluster
44-
run: bash ./scripts/konk-ci/01-kind.sh
45-
46-
- name: Install Serving
47-
run: bash ./scripts/konk-ci/02-serving.sh
32+
- name: Checkout repository
33+
uses: actions/checkout@v4
4834

49-
- name: Install Kourier
50-
run: bash ./scripts/konk-ci/02-kourier.sh
51-
52-
- name: Setup domain and autoscaler
53-
run: |
54-
INGRESS_HOST="127.0.0.1"
55-
KNATIVE_DOMAIN=$INGRESS_HOST.sslip.io
56-
kubectl patch configmap -n knative-serving config-domain -p "{\"data\": {\"$KNATIVE_DOMAIN\": \"\"}}"
57-
kubectl patch configmap -n knative-serving config-autoscaler -p "{\"data\": {\"allow-zero-initial-scale\": \"true\"}}"
58-
kubectl patch configmap -n knative-serving config-features -p "{\"data\": {\"kubernetes.podspec-affinity\": \"enabled\"}}"
59-
kubectl label node knative-control-plane loader-nodetype=worker
35+
- name: Set up Kubernetes KinD Cluster and install Knative
36+
uses: ./.github/actions/ci_knative_setup
6037

6138
- name: Build and run loader
6239
run: go run cmd/loader.go --config pkg/config/test_config.json
@@ -73,6 +50,7 @@ jobs:
7350
do
7451
kubectl logs -n default -c $container_name -l serving.knative.dev/service=${{ matrix.service }}
7552
done
53+
7654
- name: Down
7755
if: ${{ always() }}
7856
run: |
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: End-to-End Multi-Loader Tests
2+
3+
on:
4+
schedule:
5+
- cron: "0 9 * * 1"
6+
workflow_dispatch:
7+
push:
8+
branches: [main]
9+
pull_request:
10+
branches: [main]
11+
12+
env:
13+
GOOS: linux
14+
GO111MODULE: on
15+
16+
jobs:
17+
test-multi-loader:
18+
name: Test Multi-Loader with Knative Deployment
19+
env:
20+
KIND_VERSION: v0.22.0
21+
K8S_VERSION: v1.29
22+
YAML_DIR: workloads/container
23+
runs-on: ubuntu-20.04
24+
strategy:
25+
fail-fast: false
26+
steps:
27+
- name: Checkout repository
28+
uses: actions/checkout@v4
29+
30+
- name: Set up Kubernetes KinD Cluster and install Knative
31+
uses: ./.github/actions/ci_knative_setup
32+
33+
- name: Setup traces for multi trace test
34+
shell: bash
35+
run: bash ./scripts/setup/setup_multi_test_trace.sh
36+
37+
- name: Build and run multi-loader
38+
run: go run tools/multi_loader/multi_loader.go --multiLoaderConfigPath tools/multi_loader/multi_loader_config.json
39+
40+
- name: Check multi_loader output
41+
run: |
42+
# check if there are 4 output folders: *_example_1_test, *_example_2_test, *_example_3_test & dry_run
43+
folder_count=$(find data/out/multi-test/test-experiment -mindepth 1 -maxdepth 1 -type d | wc -l)
44+
if [ "$folder_count" -ne 4 ]; then
45+
echo "Output folder count is $folder_count, expected 4"
46+
exit 1
47+
else
48+
echo "Output correct number of folders"
49+
fi
50+
51+
# Check for errors in each output CSV file
52+
for file in $(find . -name "*_example_1_test/example_1_test_duration_1.csv" -o -name "*_example_2_test/example_2_test_duration_1.csv" -o -name "*_example_3_test/example_3_test_duration_1.csv"); do
53+
if [ ! -f "$file" ]; then
54+
echo "File $file not found!"
55+
exit 1
56+
fi
57+
58+
if [ $(grep true "$file" | wc -l) -ne 0 ]; then
59+
echo "Error found in $file"
60+
exit 1
61+
fi
62+
done
63+
echo "No errors found in output files"
64+
65+
- name: Down
66+
if: ${{ always() }}
67+
run: |
68+
kn service delete --all

.github/workflows/tools-tests.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
strategy:
2323
fail-fast: false
2424
matrix:
25-
module: [ tools/plotter, ]
25+
module: [ tools/plotter, tools/multi_loader/runner]
2626
steps:
2727
- name: Set up Golang
2828
uses: actions/setup-go@v5

docs/multi_loader.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Multi-Loader
2+
3+
A wrapper around loader to run multiple experiments in sequence with additional features like validation, dry-run, log collection
4+
5+
## Prerequisites
6+
As a wrapper around loader, multi-loader requires the initial cluster setup to be completed. See [vHive Loader to create a cluster](https://github.com/vhive-serverless/invitro/blob/main/docs/loader.md#create-a-cluster)
7+
8+
## Configuration
9+
### Multi-Loader Configuration
10+
| Parameter name | Data type | Possible values | Default value | Description |
11+
|---------------------|--------------------|-----------------|---------------|------------------------------------------------------------|
12+
| Studies | []LoaderStudy | N/A | N/A | A list of loader studies with their respective configurations. See [LoaderStudy](#loaderstudy) |
13+
| BaseConfigPath | string | "tools/multi_loader/base_loader_config.json" | N/A | Path to the base configuration file |
14+
| IatGeneration | bool | true, false | false | (Optional) Whether to Generate iats only and skip invocations |
15+
| Generated | bool | true, false | false | (Optional) if iats were already generated |
16+
| PreScript | string | any bash command | "" | (Optional) A global script that runs once before all experiments |
17+
| PostScript | string | any bash command | "" | (Optional) A global script that runs once after all experiments |
18+
19+
### LoaderStudy
20+
| Parameter name | Data type | Possible values | Default value | Description |
21+
|-----------------------|------------------------|-------------------------------|---------------|--------------------------------------------------------------------|
22+
| Config | map[string]interface{} | Any field in [LoaderConfiguration](https://github.com/vhive-serverless/invitro/blob/main/docs/configuration.md#loader-configuration-file-format) except `Platform`| N/A | The configuration for each loader experiment which overrides configurations in baseLoaderConfig |
23+
| Name | string | N/A | N/A | The name of the loader experiment |
24+
| TracesDir | string | N/A | N/A | Directory containing the traces for the experiment |
25+
| TracesFormat | string | "data/traces/example_{}" | N/A | Format of the trace files **The format string "{}" is required** |
26+
| TraceValues | []interface{} | ["any", 0, 1.1] | N/A | Values of the trace files Replaces the "{}" in TraceFormat |
27+
| OutputDir | string | any | data/out/{Name} | (Optional) Output directory for experiment results |
28+
| Verbosity | string | "info", "debug", "trace" | "info" | (Optional) Verbosity level for logging the experiment |
29+
| PreScript | string | any bash Command | "" | (Optional) Local script that runs this specific experiment |
30+
| PostScript | string | any bash Command | "" | (Optional) Local script that runs this specific experiment |
31+
32+
> **_Important_**:
33+
>
34+
> Only one of the following is required:
35+
> 1. `TracesDir`, or
36+
> 2. `TracesFormat` and `TraceValues`, or
37+
> 3. `TracePath` within the `LoaderExperiment`'s `Config` field
38+
>
39+
> If more than one is defined, the order of precedence is as follows:
40+
> 1. `TracesDir`,
41+
> 2. `TracesFormat` and `TraceValues`,
42+
> 3. `TracePath`
43+
>
44+
> The `Platform` field must not be overridden and should only be defined in the base config.
45+
>
46+
> The `IatGeneration` and `Generated` fields may not function as expected when handling multiple experiments due to limitations in the loader implementation.
47+
48+
> **_Note_**:
49+
>
50+
> The `Config` field follows the same structure as the [LoaderConfiguration](https://github.com/vhive-serverless/invitro/blob/main/docs/configuration.md#loader-configuration-file-format).
51+
> Any field defined in `Config` will override the corresponding value from the configuration in `BaseConfigPath`, but only for that specific experiment.
52+
> For example, if `BaseConfigPath` has `ExperimentDuration` set to 5 minutes, and you define `ExperimentDuration` as 10 minutes in `Config`, that particular experiment will run for 10 minutes instead.
53+
54+
## Command Flags
55+
56+
The multi-loader accepts the following command-line flags.
57+
58+
> **_Note_**: These flags will subsequently be used during the execution of loader.go for **<u>every experiment</u>**. If you would like to define these flag for specific experiments only, define it in [LoaderStudy](#loaderstudy)
59+
60+
Available flags:
61+
62+
- **`--multiLoaderConfig`** *(default: `tools/multi_loader/multi_loader_config.json`)*:
63+
Specifies the path to the multi-loader configuration file. This file contains settings and parameters that define how the multi-loader operates [see above](#multi-loader-configuration)
64+
65+
- **`--verbosity`** *(default: `info`)*:
66+
Sets the logging verbosity level. You can choose from the following options:
67+
- `info`: Standard information messages.
68+
- `debug`: Detailed debugging messages.
69+
- `trace`: Extremely verbose logging, including detailed execution traces.
70+
71+
- **`--failFast`** *(default: `false`)*:
72+
Determines whether the multi-loader should skip the study immediately after a failure. By default, the loader retries a failed experiment once with debug verbosity and skips the study only if the second attempt also fails. Setting this flag to `true` prevents the retry and skips the study after the first failure.
73+
74+
75+
76+
## Multi-loader Overall Flow
77+
78+
1. **Initialization**
79+
- Flags for configuration file path, verbosity, IAT generation, and execution mode are parsed
80+
- Logger is initialized based on verbosity level
81+
82+
3. **Experiment Execution Flow**
83+
- The multi-loader runner is instantiated with the provided configuration path.
84+
- A dry run is executed to validate the setup for all studies:
85+
- If any dry run fails, the execution terminates.
86+
- If all dry runs succeed, proceed to actual runs:
87+
- Global pre-scripts are executed.
88+
- Each experiment undergoes the following steps:
89+
1. **Pre-Execution Setup**
90+
- Experiment-specific pre-scripts are executed.
91+
- Necessary directories and folders are created.
92+
- Each sub-experiment is unpacked and prepared
93+
2. **Experiment Invocation**
94+
- The loader is executed with generated configurations and related flags
95+
3. **Post-Execution Steps**
96+
- Experiment-specific post-scripts are executed
97+
- Cleanup tasks are performed
98+
99+
4. **Completion**
100+
- Global post-scripts are executed.
101+
- Run Make Clean
102+
103+
### How the Dry Run Works
104+
105+
The dry run mode executes the loader with the `--dryRun` flag set to true after the unpacking of experiments defined in the multi-loader configurations.
106+
107+
In this mode, the loader performs the following actions:
108+
109+
- **Configuration Validation**: It verifies the experiment configurations without deploying any functions or generating invocations.
110+
- **Error Handling**: If a fatal error occurs at any point, the experiment will halt immediately.
111+
112+
The purpose is to ensure that your configurations are correct and to identify any potential issues before actual execution.

pkg/common/utilities.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,15 @@
2525
package common
2626

2727
import (
28+
"encoding/json"
2829
"hash/fnv"
2930
"log"
3031
"math/rand"
32+
"os/exec"
3133
"strconv"
3234
"strings"
35+
36+
logger "github.com/sirupsen/logrus"
3337
)
3438

3539
type Pair struct {
@@ -146,4 +150,42 @@ func GetName(function *Function) int {
146150
log.Fatal(err)
147151
}
148152
return functionId
149-
}
153+
}
154+
155+
func DeepCopy[T any](a T) (T, error) {
156+
var b T
157+
byt, err := json.Marshal(a)
158+
if err != nil {
159+
return b, err
160+
}
161+
err = json.Unmarshal(byt, &b)
162+
return b, err
163+
}
164+
165+
func RunScript(command string) {
166+
if command == "" {
167+
return
168+
}
169+
logger.Debug("Running command ", command)
170+
cmd, err := exec.Command("/bin/sh", command).Output()
171+
if err != nil {
172+
log.Fatal(err)
173+
}
174+
logger.Debug(string(cmd))
175+
}
176+
177+
func ParseLogType(logString string) string {
178+
logTypeArr := strings.Split(logString, "level=")
179+
if len(logTypeArr) > 1 {
180+
return strings.Split(logTypeArr[1], " ")[0]
181+
}
182+
return "info"
183+
}
184+
185+
func ParseLogMessage(logString string) string {
186+
message := strings.Split(logString, "msg=")
187+
if len(message) > 1 {
188+
return message[1][1 : len(message[1])-1]
189+
}
190+
return logString
191+
}

0 commit comments

Comments
 (0)