Skip to content

Commit

Permalink
Add benchmark workflows
Browse files Browse the repository at this point in the history
  • Loading branch information
wzshiming committed Nov 22, 2024
1 parent 73130b2 commit 28d67d2
Show file tree
Hide file tree
Showing 6 changed files with 286 additions and 9 deletions.
54 changes: 54 additions & 0 deletions .github/workflows/benchmark.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Benchmark

on:
pull_request:
paths:
- pkg/**/*
- cmd/**/*
- test/**/*
- hack/**/*
- kustomize/**/*
- go.mod
- .github/workflows/benchmark.yaml
- '!hack/releases-helm-chart.sh'
push:
paths:
- pkg/**/*
- cmd/**/*
- test/**/*
- hack/**/*
- kustomize/**/*
- go.mod
- .github/workflows/benchmark.yaml
- '!hack/releases-helm-chart.sh'

env:
CGO_ENABLED: "0"
GO_VERSION: "1.23.0"

jobs:
benchmark:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}

- name: Test Benchmark
shell: bash
run: |
./hack/e2e-test.sh e2e/kwokctl/benchmark
- name: Test Benchmark Hack
shell: bash
run: |
./hack/e2e-test.sh e2e/kwokctl/benchmark-hack
- name: Upload logs
uses: actions/upload-artifact@v4
if: failure()
with:
name: kwok-logs-benchmark
path: ${{ github.workspace }}/logs
6 changes: 0 additions & 6 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -270,12 +270,6 @@ jobs:
fi
./hack/e2e-test.sh kwokctl/kwokctl_${{ matrix.kwokctl-runtime }}
- name: Test Benchmark
if: ${{ matrix.os == 'ubuntu-latest' && matrix.kwokctl-runtime == 'binary' }}
shell: bash
run: |
./hack/e2e-test.sh e2e/kwokctl/benchmark
- name: Test Auto Detect
if: ${{ matrix.kwokctl-runtime == 'binary' }}
shell: bash
Expand Down
133 changes: 130 additions & 3 deletions test/e2e/benchmark.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package e2e
import (
"context"
"fmt"
"io"
"os/exec"
"strconv"
"strings"
Expand Down Expand Up @@ -64,6 +65,45 @@ func waitResource(ctx context.Context, t *testing.T, kwokctlPath, name, resource
}
}

func readerPodYaml(size int) io.Reader {
r, w := io.Pipe()
go func() {
defer w.Close()

Check failure on line 71 in test/e2e/benchmark.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest)

Error return value of `w.Close` is not checked (errcheck)
for i := 0; i < size; i++ {
_, _ = fmt.Fprintf(w, podYaml, i, i)
}
}()
return r
}

var podYaml = `
apiVersion: v1
kind: Pod
metadata:
name: pod-%d
namespace: default
uid: 00000000-0000-0000-0001-%012d
spec:
containers:
- image: busybox
name: container-0
nodeName: node-0
---
`

func scaleCreatePodWithHack(ctx context.Context, t *testing.T, kwokctlPath string, name string, size int) error {
scaleCmd := exec.CommandContext(ctx, kwokctlPath, "--name", name, "hack", "put", "--path", "-")
scaleCmd.Stdin = readerPodYaml(size)
if err := scaleCmd.Start(); err != nil {
return fmt.Errorf("failed to start scale command: %w", err)
}

if err := waitResource(ctx, t, kwokctlPath, name, "Pod", "Running", size, 5, 10); err != nil {
return fmt.Errorf("failed to wait for resource: %w", err)
}
return nil
}

func scaleCreatePod(ctx context.Context, t *testing.T, kwokctlPath string, name string, size int) error {
cmd := exec.CommandContext(ctx, kwokctlPath, "--name", name, "kubectl", "get", "node", "-o", "jsonpath={.items.*.metadata.name}") // #nosec G204
out, err := cmd.Output()
Expand Down Expand Up @@ -105,6 +145,59 @@ func scaleDeletePod(ctx context.Context, t *testing.T, kwokctlPath string, name
return nil
}

func readerNodeYaml(size int) io.Reader {
r, w := io.Pipe()
go func() {
defer w.Close()

Check failure on line 151 in test/e2e/benchmark.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest)

Error return value of `w.Close` is not checked (errcheck)
for i := 0; i < size; i++ {
_, _ = fmt.Fprintf(w, nodeYaml, i, i)
}
}()
return r
}

var nodeYaml = `
apiVersion: v1
kind: Node
metadata:
annotations:
kwok.x-k8s.io/node: fake
node.alpha.kubernetes.io/ttl: "0"
labels:
beta.kubernetes.io/arch: amd64
beta.kubernetes.io/os: linux
kubernetes.io/arch: amd64
kubernetes.io/os: linux
kubernetes.io/role: agent
node-role.kubernetes.io/agent: ""
type: kwok
name: node-%d
uid: 00000000-0000-0000-0000-%012d
status:
allocatable:
cpu: "32"
memory: 256Gi
pods: "110"
capacity:
cpu: "32"
memory: 256Gi
pods: "110"
---
`

func scaleCreateNodeWithHack(ctx context.Context, t *testing.T, kwokctlPath string, name string, size int) error {
scaleCmd := exec.CommandContext(ctx, kwokctlPath, "--name", name, "hack", "put", "--path", "-")
scaleCmd.Stdin = readerNodeYaml(size)
if err := scaleCmd.Start(); err != nil {
return fmt.Errorf("failed to start scale command: %w", err)
}

if err := waitResource(ctx, t, kwokctlPath, name, "Node", "Ready", size, 10, 10); err != nil {
return fmt.Errorf("failed to wait for resource: %w", err)
}
return nil
}

func scaleCreateNode(ctx context.Context, t *testing.T, kwokctlPath string, name string, size int) error {
scaleCmd := exec.CommandContext(ctx, kwokctlPath, "--name", name, "scale", "node", "fake-node", "--replicas", strconv.Itoa(size)) // #nosec G204
if err := scaleCmd.Start(); err != nil {
Expand All @@ -120,10 +213,44 @@ func scaleCreateNode(ctx context.Context, t *testing.T, kwokctlPath string, name
func CaseBenchmark(kwokctlPath, clusterName string) *features.FeatureBuilder {
return features.New("Benchmark").
Assess("Create nodes", func(ctx context.Context, t *testing.T, c *envconf.Config) context.Context {
ctx0, cancel := context.WithTimeout(ctx, 120*time.Second)
ctx0, cancel := context.WithTimeout(ctx, 180*time.Second)
defer cancel()

err := scaleCreateNode(ctx0, t, kwokctlPath, clusterName, 5000)
if err != nil {
t.Fatal(err)
}
return ctx
}).
Assess("Create pods", func(ctx context.Context, t *testing.T, c *envconf.Config) context.Context {
ctx0, cancel := context.WithTimeout(ctx, 240*time.Second)
defer cancel()

err := scaleCreatePod(ctx0, t, kwokctlPath, clusterName, 10000)
if err != nil {
t.Fatal(err)
}
return ctx
}).
Assess("Delete pods", func(ctx context.Context, t *testing.T, c *envconf.Config) context.Context {
ctx0, cancel := context.WithTimeout(ctx, 240*time.Second)
defer cancel()

err := scaleDeletePod(ctx0, t, kwokctlPath, clusterName, 0)
if err != nil {
t.Fatal(err)
}
return ctx
})
}

func CaseBenchmarkWithHack(kwokctlPath, clusterName string) *features.FeatureBuilder {
return features.New("Benchmark").
Assess("Create nodes", func(ctx context.Context, t *testing.T, c *envconf.Config) context.Context {
ctx0, cancel := context.WithTimeout(ctx, 180*time.Second)
defer cancel()

err := scaleCreateNode(ctx0, t, kwokctlPath, clusterName, 2000)
err := scaleCreateNodeWithHack(ctx0, t, kwokctlPath, clusterName, 5000)
if err != nil {
t.Fatal(err)
}
Expand All @@ -133,7 +260,7 @@ func CaseBenchmark(kwokctlPath, clusterName string) *features.FeatureBuilder {
ctx0, cancel := context.WithTimeout(ctx, 240*time.Second)
defer cancel()

err := scaleCreatePod(ctx0, t, kwokctlPath, clusterName, 5000)
err := scaleCreatePodWithHack(ctx0, t, kwokctlPath, clusterName, 10000)
if err != nil {
t.Fatal(err)
}
Expand Down
29 changes: 29 additions & 0 deletions test/e2e/kwokctl/benchmark-hack/kubectl_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
Copyright 2024 The Kubernetes Authors.
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 benchmark_hack_test

import (
"testing"

"sigs.k8s.io/kwok/test/e2e"
)

func TestBenchmarkWithHack(t *testing.T) {
f0 := e2e.CaseBenchmarkWithHack(kwokctlPath, clusterName).
Feature()
testEnv.Test(t, f0)
}
72 changes: 72 additions & 0 deletions test/e2e/kwokctl/benchmark-hack/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
Copyright 2024 The Kubernetes Authors.
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 benchmark_hack_test is a test benchmarking environment for kwok.
package benchmark_hack_test

import (
"os"
"runtime"
"testing"

"sigs.k8s.io/e2e-framework/pkg/env"
"sigs.k8s.io/e2e-framework/pkg/envconf"
"sigs.k8s.io/e2e-framework/support/kwok"

"sigs.k8s.io/kwok/pkg/consts"
"sigs.k8s.io/kwok/pkg/utils/path"
"sigs.k8s.io/kwok/test/e2e/helper"
)

var (
runtimeEnv = consts.RuntimeTypeBinary
testEnv env.Environment
pwd = os.Getenv("PWD")
rootDir = path.Join(pwd, "../../../..")
logsDir = path.Join(rootDir, "logs")
clusterName = envconf.RandomName("kwok-e2e-benchmark-hack", 24)
kwokPath = path.Join(rootDir, "bin", runtime.GOOS, runtime.GOARCH, "kwok"+helper.BinSuffix)
kwokctlPath = path.Join(rootDir, "bin", runtime.GOOS, runtime.GOARCH, "kwokctl"+helper.BinSuffix)
baseArgs = []string{
"--kwok-controller-binary=" + kwokPath,
"--runtime=" + runtimeEnv,
"--wait=15m",
"--disable-kube-scheduler",
"--disable-qps-limits",
}
)

func init() {
_ = os.Setenv("KWOK_WORKDIR", path.Join(rootDir, "workdir"))
}

func TestMain(m *testing.M) {
testEnv = helper.Environment()

k := kwok.NewProvider().
WithName(clusterName).
WithPath(kwokctlPath)
testEnv.Setup(
helper.BuildKwokBinary(rootDir),
helper.BuildKwokctlBinary(rootDir),
helper.CreateCluster(k, baseArgs...),
)
testEnv.Finish(
helper.ExportLogs(k, logsDir),
helper.DestroyCluster(k),
)
os.Exit(testEnv.Run(m))
}
1 change: 1 addition & 0 deletions test/e2e/kwokctl/benchmark/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ var (
"--runtime=" + runtimeEnv,
"--wait=15m",
"--disable-kube-scheduler",
"--disable-qps-limits",
}
)

Expand Down

0 comments on commit 28d67d2

Please sign in to comment.