Skip to content

Instantly share code, notes, and snippets.

@kunalkushwaha
Last active October 23, 2018 00:29
Show Gist options
  • Save kunalkushwaha/4504487b0b43dbbe1421069cd50eb08c to your computer and use it in GitHub Desktop.
Save kunalkushwaha/4504487b0b43dbbe1421069cd50eb08c to your computer and use it in GitHub Desktop.
podman's performance test program (libpod as library)
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/containers/libpod/libpod"
cc "github.com/containers/libpod/pkg/spec"
"github.com/containers/libpod/pkg/util"
"github.com/containers/storage/pkg/reexec"
"github.com/pkg/profile"
)
const (
TestImageName = "docker.io/library/alpine:latest"
ContainersCount = 50
)
type profileData struct {
minCreate, minStart, minStop, minDel time.Duration
avgCreate, avgStart, avgStop, avgDel time.Duration
maxCreate, maxStart, maxStop, maxDel time.Duration
}
func main() {
if reexec.Init() {
return
}
log.Flags()
log.SetFlags(2)
opts := defaultRuntimeOptions()
client, err := libpod.NewRuntime(opts...)
if err != nil {
log.Fatal(err)
}
defer client.Shutdown(false)
// Print Runtime & System Information.
runtimeInfo, err := client.GetOCIRuntimeVersion()
if err != nil {
log.Fatal(err)
}
fmt.Println(runtimeInfo)
imageRuntime := client.ImageRuntime()
if imageRuntime == nil {
log.Fatal("ImageRuntime is null")
}
// Enable profiling.
// CPU Profile
defer profile.Start().Stop()
//Prepare for test.
// Pull images
testImage, err := imageRuntime.NewFromLocal(TestImageName)
if err != nil {
//TODO: Download the image from dockerhub.
log.Fatal(err)
}
ctx := context.Background()
imageName := ""
names := testImage.Names()
if len(names) > 0 {
imageName = names[0]
} else {
imageName = testImage.ID()
}
idmappings, err := util.ParseIDMapping(nil, nil, "", "")
if err != nil {
log.Fatal(err)
}
config := &cc.CreateConfig{
Tty: true,
Image: imageName,
ImageID: testImage.ID(),
IDMappings: idmappings,
Command: []string{"/bin/sh"},
WorkDir: "/",
}
runtimeSpec, err := cc.CreateConfigToOCISpec(config)
if err != nil {
log.Fatal(err)
}
data := new(profileData)
for i := 0; i <= ContainersCount; i++ {
//Create Container
createStartTime := time.Now()
ctr, err := client.NewContainer(ctx, runtimeSpec, libpod.WithRootFSFromImage(testImage.ID(), imageName, false))
if err != nil {
log.Fatal(err)
}
createTotalTime := time.Now().Sub(createStartTime)
fmt.Println("Image Created : ", ctr.ID()[:12])
state, _ := ctr.State()
fmt.Println("Container Status: ", state.String())
// Start container
startStartTime := time.Now()
err = ctr.Start(ctx)
if err != nil {
log.Fatal(err)
}
startTotalTime := time.Now().Sub(startStartTime)
state, _ = ctr.State()
fmt.Println("Container Status: ", state.String())
//Stop Container
stopStartTime := time.Now()
err = ctr.Stop()
if err != nil {
log.Fatal(err)
}
stopTotalTime := time.Now().Sub(stopStartTime)
state, _ = ctr.State()
fmt.Println("Container Status: ", state.String())
//Delete Container
deleteStartTime := time.Now()
/*
err = client.RemoveContainer(ctx, ctr, true)
if err != nil {
log.Fatal(err)
}
*/
deleteTotalTime := time.Now().Sub(deleteStartTime)
data = updateProfileData(data, createTotalTime, startTotalTime, stopTotalTime, deleteTotalTime)
}
fmt.Println("\nContainer Profile data\n")
fmt.Printf("\tCreate\tStart\tStop\tDelete\n")
fmt.Printf("Min\t%.2fs\t%.2fs\t%.2fs\t%.2fs\n", data.minCreate.Seconds(), data.minStart.Seconds(), data.minStop.Seconds(), data.minDel.Seconds())
fmt.Printf("Avg\t%.2fs\t%.2fs\t%.2fs\t%.2fs\n", data.avgCreate.Seconds()/ContainersCount, data.avgStart.Seconds()/ContainersCount, data.avgStop.Seconds()/ContainersCount, data.avgDel.Seconds()/ContainersCount)
fmt.Printf("Max\t%.2fs\t%.2fs\t%.2fs\t%.2fs\n", data.maxCreate.Seconds(), data.maxStart.Seconds(), data.maxStop.Seconds(), data.maxDel.Seconds())
fmt.Printf("Total\t%.2fs\t%.2fs\t%.2fs\t%.2fs\n", data.avgCreate.Seconds(), data.avgStart.Seconds(), data.avgStop.Seconds(), data.avgDel.Seconds())
}
func defaultRuntimeOptions() []libpod.RuntimeOption {
options := []libpod.RuntimeOption{}
return options
/*
//TODO: Shall we test in clean environment?
sOpts := storage.StoreOptions{
GraphDriverName: "overlay",
RunRoot: "/var/run/containers/storage",
GraphRoot: "/var/lib/containers/storage",
}
storageOpts := libpod.WithStorageConfig(sOpts)
options = append(options, storageOpts)
return options
*/
}
func updateProfileData(base *profileData, create, start, stop, delete time.Duration) *profileData {
if create < base.minCreate || base.minCreate == 0 {
base.minCreate = create
}
if create > base.maxCreate || base.maxCreate == 0 {
base.maxCreate = create
}
if start < base.minStart || base.minStart == 0 {
base.minStart = start
}
if start > base.maxStart || base.maxStart == 0 {
base.maxStart = start
}
if stop < base.minStop || base.minStop == 0 {
base.minStop = stop
}
if stop > base.maxStop || base.maxStop == 0 {
base.maxStop = stop
}
if delete < base.minDel || base.minDel == 0 {
base.minDel = delete
}
if delete > base.maxDel || base.maxDel == 0 {
base.maxDel = delete
}
base.avgCreate = base.avgCreate + create
base.avgStart = base.avgStart + start
base.avgStop = base.avgStop + stop
base.avgDel = base.avgDel + delete
return base
}
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment