This repository has been archived by the owner on Nov 9, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from nicolevanderhoeven/main
add xk6-chaos summary
- Loading branch information
Showing
8 changed files
with
248 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,30 @@ | ||
import chaos from 'k6/x/chaos'; | ||
import { Pods } from 'k6/x/chaos/k8s'; | ||
import { Podkillers } from 'k6/x/chaos/experiments'; | ||
import { textSummary } from 'https://jslib.k6.io/k6-summary/0.0.1/index.js'; | ||
|
||
export default function () { | ||
console.log(`Running simskij/xk6-chaos@${chaos.version}.`); | ||
const p = new Pods(); | ||
console.log( | ||
`There are currently ${p.list().length} pods in the default namespace.` | ||
); | ||
killPod(p); | ||
console.log( | ||
`There are now ${p.list().length} pods in the default namespace.` | ||
); | ||
killPod(); | ||
} | ||
|
||
function killPod(p) { | ||
const victim = p.list()[0]; | ||
console.log(`Killing pod ${victim}`); | ||
p.killByName('media', victim); | ||
// The killPod function terminates a pod within a Kubernetes cluster according to specifications provided. | ||
export function killPod() { | ||
|
||
// Instantiate a new Podkiller object | ||
const podkiller = new Podkillers(); | ||
|
||
// The line below terminates a random pod in the specified namespace. | ||
// podkiller.killRandomPod('default'); | ||
|
||
// The line below kills a pod within the namespace whose name exactly matches "web-7d55cf8588-7bxpv". | ||
// podkiller.killPod('default', 'web-7d55cf8588-7bxpv'); | ||
|
||
// The line below terminates a pod within the namespace whose name contains "web" | ||
podkiller.killPodLike('default', 'web'); | ||
|
||
} | ||
|
||
// The handleSummary function creates a summary of the chaos experiments after the standard k6 summary. | ||
export function handleSummary(data) { | ||
return { | ||
'stdout': textSummary(data, { indent: ' ', enableColors: true}) + new Podkillers().generateSummary(), | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package experiments | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/simskij/xk6-chaos/internal/experiments/podkillers" | ||
"go.k6.io/k6/js/common" | ||
"go.k6.io/k6/js/modules" | ||
) | ||
|
||
|
||
// Register the extension on module initialization, available to | ||
// import from JS as "k6/x/chaos/experiments". | ||
func init() { | ||
modules.Register("k6/x/chaos/experiments", &Experiments{ | ||
// Podkiller: podkillers.New(), | ||
}) | ||
// i++ | ||
} | ||
|
||
// This exposes experiment metadata for use in displaying results. | ||
type Experiments struct { | ||
Podkiller *podkillers.Podkillers | ||
Summary string | ||
} | ||
|
||
// XPodkillers serves as a constructor of the Podkillers js class | ||
func (*Experiments) XPodkillers(ctx *context.Context) (interface{}, error) { | ||
rt := common.GetRuntime(*ctx) | ||
p := podkillers.New() | ||
return common.Bind(rt, p, ctx), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package podkillers | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"time" | ||
|
||
"github.com/simskij/xk6-chaos/internal/experiments/summary" | ||
"github.com/simskij/xk6-chaos/internal/k8s/pods" | ||
"github.com/simskij/xk6-chaos/pkg/k8s/client" | ||
) | ||
|
||
// This exposes podkiller metadata for use in displaying results. | ||
type Podkillers struct { | ||
Id int | ||
ExperimentType string | ||
NumOfPodsBefore int | ||
NumOfPodsAfter int | ||
Victims string | ||
pod *pods.Pods | ||
} | ||
|
||
var ExperimentNumber = 1 | ||
|
||
// New creates a new podkiller | ||
func New() *Podkillers { | ||
experimentNum := ExperimentNumber | ||
ExperimentNumber++ | ||
c, err := client.New() | ||
p := pods.New(c) | ||
if err != nil { | ||
return nil | ||
} | ||
return &Podkillers{experimentNum, "Pod termination", 0, 0, "", p} | ||
} | ||
|
||
// AddResults saves the names of pods selected to be terminated. | ||
func (p *Podkillers) AddResults(namespace string, victim string) { | ||
p.GetNumOfPods(namespace) | ||
|
||
sum := summary.GetSummary() | ||
sum.AddResult(summary.PodkillerResult{ | ||
Victim: victim, | ||
Timestamp: p.Timestamp(), | ||
PodCount: summary.PodCount{ | ||
Before: p.NumOfPodsBefore, | ||
After: p.NumOfPodsAfter, | ||
}, | ||
}) | ||
} | ||
|
||
// SetStartingPods saves the number of pods at the beginning of a test as the "before" state. | ||
func (p *Podkillers) SetStartingPods(number int) { | ||
p.NumOfPodsBefore = number | ||
} | ||
|
||
// GetStartingPods returns and saves the number of pods at the beginning of the test for reporting purposes. | ||
func (p *Podkillers) GetStartingPods(namespace string) int { | ||
var podsAlive, _ = p.pod.List(context.Background(), namespace) | ||
p.NumOfPodsBefore = len(podsAlive) | ||
return p.NumOfPodsBefore | ||
} | ||
|
||
// GetNumOfPods returns and saves the current number of pods. | ||
func (p *Podkillers) GetNumOfPods(namespace string) int { | ||
time.Sleep(5 * time.Second) | ||
var podsAlive, _ = p.pod.List(context.Background(), namespace) | ||
p.NumOfPodsAfter = len(podsAlive) | ||
return p.NumOfPodsAfter | ||
} | ||
|
||
// KillPod terminates a k8s pod identified by name. | ||
func (p *Podkillers) KillPod(namespace string, podName string) error { | ||
p.GetStartingPods(namespace) | ||
err := p.pod.KillByName(context.Background(), namespace, podName) | ||
p.AddResults(namespace, podName) | ||
return err | ||
} | ||
|
||
// KillPodLike terminates a k8s pod whose name contains string. | ||
func (p *Podkillers) KillPodLike(namespace string, keyword string) error { | ||
p.GetStartingPods(namespace) | ||
podName, err := p.pod.KillByKeyword(context.Background(), namespace, keyword) | ||
p.AddResults(namespace, podName) | ||
return err | ||
} | ||
|
||
// KillRandomPod terminates a pod at random. | ||
func (p *Podkillers) KillRandomPod(namespace string) error { | ||
p.GetStartingPods(namespace) | ||
podName, err := p.pod.KillRandom(context.Background(), namespace) | ||
p.AddResults(namespace, podName) | ||
return err | ||
} | ||
|
||
// Timestamp constructs the format of a timestamp for logging purposes | ||
func (p *Podkillers) Timestamp() string { | ||
dt := time.Now() | ||
tsMsg := dt.Format("2006-Jan-02 15:04:05") | ||
return tsMsg | ||
} | ||
|
||
func (p *Podkillers) GenerateSummary() string { | ||
sum := summary.GetSummary() | ||
output := "\n\nxk6-chaos\n===\n\nPODKILLERS:\n" | ||
for i, result := range sum.Results { | ||
output += fmt.Sprintf( | ||
" Victim #%d: %s terminated at %s\n Pods before: %d; Pods 5s after termination: %d\n", | ||
i, | ||
result.Victim, | ||
result.Timestamp, | ||
result.PodCount.Before, | ||
result.PodCount.After, | ||
) | ||
} | ||
return output + "\n" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package summary | ||
|
||
var summary *Summary | ||
|
||
func GetSummary() *Summary { | ||
if summary == nil { | ||
summary = &Summary{} | ||
} | ||
return summary | ||
} | ||
|
||
func (s *Summary) AddResult(result PodkillerResult) { | ||
s.Results = append(s.Results, result) | ||
} | ||
|
||
func (s *Summary) GetResults() []PodkillerResult { | ||
return s.Results | ||
} | ||
|
||
type Summary struct { | ||
Results []PodkillerResult | ||
} | ||
|
||
type PodkillerResult struct { | ||
Victim string | ||
PodCount PodCount | ||
Timestamp string | ||
} | ||
|
||
type PodCount struct { | ||
Before int | ||
After int | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters