Skip to content

Commit

Permalink
Return lazily evaluated objects from k6/execution
Browse files Browse the repository at this point in the history
  • Loading branch information
Ivan Mirić committed May 20, 2021
1 parent 7a79e79 commit 69aad0a
Showing 1 changed file with 94 additions and 22 deletions.
116 changes: 94 additions & 22 deletions js/modules/k6/execution/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import (
"context"
"errors"

"github.com/dop251/goja"

"go.k6.io/k6/js/common"
"go.k6.io/k6/lib"
)

Expand All @@ -36,61 +39,130 @@ func New() *Execution {
}

// GetVUStats returns information about the currently executing VU.
func (e *Execution) GetVUStats(ctx context.Context) (map[string]interface{}, error) {
func (e *Execution) GetVUStats(ctx context.Context) (goja.Value, error) {
vuState := lib.GetState(ctx)
if vuState == nil {
return nil, errors.New("getting VU information in the init context is not supported")
}

rt := common.GetRuntime(ctx)
if rt == nil {
return nil, errors.New("goja runtime is nil in context")
}

scID, _ := vuState.GetScenarioVUID()
out := map[string]interface{}{
"id": vuState.Vu,
"idScenario": scID,
"iteration": vuState.Iteration,
"iterationScenario": vuState.GetScenarioVUIter(),
stats := map[string]interface{}{
"id": vuState.Vu,
"idScenario": scID,
"iteration": vuState.Iteration,
"iterationScenario": func() goja.Value {
return rt.ToValue(vuState.GetScenarioVUIter())
},
}

obj, err := newLazyJSObject(rt, stats)
if err != nil {
return nil, err
}

return out, nil
return obj, nil
}

// GetScenarioStats returns information about the currently executing scenario.
func (e *Execution) GetScenarioStats(ctx context.Context) (map[string]interface{}, error) {
func (e *Execution) GetScenarioStats(ctx context.Context) (goja.Value, error) {
ss := lib.GetScenarioState(ctx)
if ss == nil {
return nil, errors.New("getting scenario information in the init context is not supported")
}

progress, _ := ss.ProgressFn()
out := map[string]interface{}{
rt := common.GetRuntime(ctx)
if rt == nil {
return nil, errors.New("goja runtime is nil in context")
}

stats := map[string]interface{}{
"name": ss.Name,
"executor": ss.Executor,
"startTime": ss.StartTime,
"progress": progress,
"iteration": ss.GetIter(),
"progress": func() goja.Value {
p, _ := ss.ProgressFn()
return rt.ToValue(p)
},
"iteration": func() goja.Value {
return rt.ToValue(ss.GetIter())
},
}

if ss.GetGlobalIter != nil {
out["iterationGlobal"] = ss.GetGlobalIter()
stats["iterationGlobal"] = func() goja.Value {
return rt.ToValue(ss.GetGlobalIter())
}
}

obj, err := newLazyJSObject(rt, stats)
if err != nil {
return nil, err
}

return out, nil
return obj, nil
}

// GetTestStats returns global test information.
func (e *Execution) GetTestStats(ctx context.Context) (map[string]interface{}, error) {
func (e *Execution) GetTestStats(ctx context.Context) (goja.Value, error) {
es := lib.GetExecutionState(ctx)
if es == nil {
return nil, errors.New("getting test information in the init context is not supported")
}

out := map[string]interface{}{
rt := common.GetRuntime(ctx)
if rt == nil {
return nil, errors.New("goja runtime is nil in context")
}

stats := map[string]interface{}{
// XXX: For consistency, should this be startTime instead, or startTime
// in ScenarioStats be converted to duration?
"duration": es.GetCurrentTestRunDuration().String(),
"iterationsCompleted": es.GetFullIterationCount(),
"iterationsInterrupted": es.GetPartialIterationCount(),
"vusActive": es.GetCurrentlyActiveVUsCount(),
"vusMax": es.GetInitializedVUsCount(),
"duration": func() goja.Value {
return rt.ToValue(es.GetCurrentTestRunDuration().String())
},
"iterationsCompleted": func() goja.Value {
return rt.ToValue(es.GetFullIterationCount())
},
"iterationsInterrupted": func() goja.Value {
return rt.ToValue(es.GetPartialIterationCount())
},
"vusActive": func() goja.Value {
return rt.ToValue(es.GetCurrentlyActiveVUsCount())
},
"vusMax": func() goja.Value {
return rt.ToValue(es.GetInitializedVUsCount())
},
}

obj, err := newLazyJSObject(rt, stats)
if err != nil {
return nil, err
}

return obj, nil
}

func newLazyJSObject(rt *goja.Runtime, data map[string]interface{}) (goja.Value, error) {
obj := rt.NewObject()

for k, v := range data {
if val, ok := v.(func() goja.Value); ok {
if err := obj.DefineAccessorProperty(k, rt.ToValue(val),
nil, goja.FLAG_FALSE, goja.FLAG_TRUE); err != nil {
return nil, err
}
} else {
if err := obj.DefineDataProperty(k, rt.ToValue(v),
goja.FLAG_FALSE, goja.FLAG_FALSE, goja.FLAG_TRUE); err != nil {
return nil, err
}
}
}

return out, nil
return obj, nil
}

0 comments on commit 69aad0a

Please sign in to comment.