Skip to content

Commit c618076

Browse files
authored
Merge pull request #398 from kzys/benchmark
Benchmark CreateVM and StopVM
2 parents f7734c5 + ace03d7 commit c618076

File tree

3 files changed

+146
-1
lines changed

3 files changed

+146
-1
lines changed

runtime/Makefile

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,28 @@ integ-test-%: logs
7272
$(FIRECRACKER_CONTAINERD_TEST_IMAGE):$(DOCKER_IMAGE_TAG) \
7373
"go test $(EXTRAGOARGS) -run '^$(subst integ-test-,,$@)$$'"
7474

75+
benchmark-%: logs
76+
$(CURDIR)/../tools/thinpool.sh reset "$(FICD_DM_POOL)"
77+
docker run --rm -it \
78+
--privileged \
79+
--ipc=host \
80+
--network=none \
81+
--volume /dev:/dev \
82+
--volume /run/udev/control:/run/udev/control \
83+
--volume $(CURDIR)/logs:/var/log/firecracker-containerd-test \
84+
--volume $(CURDIR)/..:/src \
85+
--volume $(GO_CACHE_VOLUME_NAME):/go \
86+
--env ENABLE_ISOLATED_TESTS=1 \
87+
--env FICD_DM_VOLUME_GROUP=$(FICD_DM_VOLUME_GROUP) \
88+
--env FICD_DM_POOL=$(FICD_DM_POOL) \
89+
--env GOPROXY=direct \
90+
--env GOSUMDB=off \
91+
--env NUMBER_OF_VMS=$(NUMBER_OF_VMS) \
92+
--workdir="/src/runtime" \
93+
--init \
94+
$(FIRECRACKER_CONTAINERD_TEST_IMAGE):$(DOCKER_IMAGE_TAG) \
95+
"go test $(EXTRAGOARGS) -run IGNORE -bench '$(subst benchmark-,,$@)'"
96+
7597
logs:
7698
mkdir logs
7799

runtime/benchmark_test.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
// Copyright 2018-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"). You may
4+
// not use this file except in compliance with the License. A copy of the
5+
// License is located at
6+
//
7+
// http://aws.amazon.com/apache2.0/
8+
//
9+
// or in the "license" file accompanying this file. This file is distributed
10+
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
// express or implied. See the License for the specific language governing
12+
// permissions and limitations under the License.
13+
14+
package main
15+
16+
import (
17+
"context"
18+
"testing"
19+
"time"
20+
21+
"github.com/containerd/containerd"
22+
"github.com/containerd/containerd/namespaces"
23+
"github.com/containerd/containerd/pkg/ttrpcutil"
24+
"github.com/firecracker-microvm/firecracker-containerd/proto"
25+
fccontrol "github.com/firecracker-microvm/firecracker-containerd/proto/service/fccontrol/ttrpc"
26+
"github.com/gofrs/uuid"
27+
"github.com/stretchr/testify/require"
28+
)
29+
30+
func createAndStopVM(
31+
ctx context.Context,
32+
fcClient fccontrol.FirecrackerService,
33+
request proto.CreateVMRequest,
34+
) error {
35+
uuid, err := uuid.NewV4()
36+
if err != nil {
37+
return err
38+
}
39+
40+
request.VMID = uuid.String()
41+
42+
_, err = fcClient.CreateVM(ctx, &request)
43+
if err != nil {
44+
return err
45+
}
46+
47+
_, err = fcClient.StopVM(ctx, &proto.StopVMRequest{VMID: request.VMID})
48+
if err != nil {
49+
return err
50+
}
51+
52+
return nil
53+
}
54+
55+
func benchmarkCreateAndStopVM(b *testing.B, vcpuCount uint32, kernelArgs string, parallel int) {
56+
require := require.New(b)
57+
58+
client, err := containerd.New(containerdSockPath, containerd.WithDefaultRuntime(firecrackerRuntime))
59+
require.NoError(err, "unable to create client to containerd service at %s, is containerd running?", containerdSockPath)
60+
defer client.Close()
61+
62+
ctx := namespaces.WithNamespace(context.Background(), "default")
63+
64+
pluginClient, err := ttrpcutil.NewClient(containerdSockPath + ".ttrpc")
65+
require.NoError(err, "failed to create ttrpc client")
66+
67+
fcClient := fccontrol.NewFirecrackerClient(pluginClient.Client())
68+
request := proto.CreateVMRequest{
69+
KernelArgs: kernelArgs,
70+
MachineCfg: &proto.FirecrackerMachineConfiguration{
71+
VcpuCount: vcpuCount,
72+
},
73+
}
74+
75+
ch := make(chan error, parallel)
76+
for i := 0; i < parallel; i++ {
77+
go func() {
78+
var err error
79+
defer func() {
80+
ch <- err
81+
}()
82+
83+
for i := 0; i < b.N; i++ {
84+
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
85+
defer cancel()
86+
87+
err = createAndStopVM(ctx, fcClient, request)
88+
if err != nil {
89+
return
90+
}
91+
}
92+
}()
93+
}
94+
95+
// Make sure all goroutines are finished successfully.
96+
for i := 0; i < parallel; i++ {
97+
require.NoError(<-ch)
98+
}
99+
}
100+
101+
func BenchmarkCreateAndStopVM_Vcpu1_Isolated(b *testing.B) {
102+
prepareIntegTest(b)
103+
benchmarkCreateAndStopVM(b, 1, defaultRuntimeConfig.KernelArgs, 1)
104+
}
105+
func BenchmarkCreateAndStopVM_Vcpu5_Isolated(b *testing.B) {
106+
prepareIntegTest(b)
107+
benchmarkCreateAndStopVM(b, 5, defaultRuntimeConfig.KernelArgs, 1)
108+
}
109+
110+
func BenchmarkCreateAndStopVM_Quiet_Isolated(b *testing.B) {
111+
prepareIntegTest(b)
112+
benchmarkCreateAndStopVM(
113+
b,
114+
1,
115+
// Same as https://github.com/firecracker-microvm/firecracker-demo/blob/c22499567b63b4edd85e19ca9b0e9fa398b3300b/start-firecracker.sh#L9
116+
"ro noapic reboot=k panic=1 pci=off nomodules systemd.log_color=false systemd.unit=firecracker.target init=/sbin/overlay-init tsc=reliable quiet 8250.nr_uarts=0 ipv6.disable=1",
117+
1,
118+
)
119+
}
120+
func BenchmarkCreateAndStopVM_Parallel10_Isolated(b *testing.B) {
121+
prepareIntegTest(b)
122+
benchmarkCreateAndStopVM(b, 1, defaultRuntimeConfig.KernelArgs, 10)
123+
}

runtime/integ_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func shimBaseDir() string {
5858
// devmapper is the only snapshotter we can use with Firecracker
5959
const defaultSnapshotterName = "devmapper"
6060

61-
func prepareIntegTest(t *testing.T, options ...func(*config.Config)) {
61+
func prepareIntegTest(t testing.TB, options ...func(*config.Config)) {
6262
t.Helper()
6363

6464
internal.RequiresIsolation(t)

0 commit comments

Comments
 (0)