Unverified Commit c66f1057 authored by Rafał Augustyniak's avatar Rafał Augustyniak Committed by GitHub
Browse files

experimentation: add additional capabilities to transformer (#610)

* Add the support for the list of transformations of a given type to the Transformer
* Add transformations that receive both configuration and run when they are performed
parent 9710adc0
Showing with 236 additions and 137 deletions
+236 -137
......@@ -9,7 +9,7 @@ option go_package = "github.com/lyft/clutch/backend/api/chaos/experimentation/v1
// ListViewItem an abstraction for a list item.
message ListViewItem {
// The unique identifier of a list item.
uint64 identifier = 1;
uint64 id = 1;
// The properties map.
PropertiesMap properties = 2;
}
......@@ -32,7 +32,7 @@ type ListViewItem struct {
unknownFields protoimpl.UnknownFields
// The unique identifier of a list item.
Identifier uint64 `protobuf:"varint,1,opt,name=identifier,proto3" json:"identifier,omitempty"`
Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
// The properties map.
Properties *PropertiesMap `protobuf:"bytes,2,opt,name=properties,proto3" json:"properties,omitempty"`
}
......@@ -69,9 +69,9 @@ func (*ListViewItem) Descriptor() ([]byte, []int) {
return file_chaos_experimentation_v1_list_view_item_proto_rawDescGZIP(), []int{0}
}
func (x *ListViewItem) GetIdentifier() uint64 {
func (x *ListViewItem) GetId() uint64 {
if x != nil {
return x.Identifier
return x.Id
}
return 0
}
......@@ -93,10 +93,9 @@ var file_chaos_experimentation_v1_list_view_item_proto_rawDesc = []byte{
0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31,
0x1a, 0x29, 0x63, 0x68, 0x61, 0x6f, 0x73, 0x2f, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65,
0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65,
0x72, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x7e, 0x0a, 0x0c, 0x4c,
0x69, 0x73, 0x74, 0x56, 0x69, 0x65, 0x77, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1e, 0x0a, 0x0a, 0x69,
0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52,
0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x4e, 0x0a, 0x0a, 0x70,
0x72, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6e, 0x0a, 0x0c, 0x4c,
0x69, 0x73, 0x74, 0x56, 0x69, 0x65, 0x77, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x69,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x4e, 0x0a, 0x0a, 0x70,
0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x2e, 0x2e, 0x63, 0x6c, 0x75, 0x74, 0x63, 0x68, 0x2e, 0x63, 0x68, 0x61, 0x6f, 0x73, 0x2e, 0x65,
0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76,
......
......@@ -44,7 +44,7 @@ func (m *ListViewItem) Validate() error {
return nil
}
// no validation rules for Identifier
// no validation rules for Id
if v, ok := interface{}(m.GetProperties()).(interface{ Validate() error }); ok {
if err := v.Validate(); err != nil {
......
......@@ -42,11 +42,11 @@ func New(_ *any.Any, logger *zap.Logger, scope tally.Scope) (module.Module, erro
}
func (s *Service) Register(r module.Registrar) error {
transformation := experimentstore.Transformation{ConfigTypeUrl: "type.googleapis.com/clutch.chaos.serverexperimentation.v1.TestConfig", ConfigTransform: s.transform}
transformation := experimentstore.Transformation{ConfigTypeUrl: "type.googleapis.com/clutch.chaos.serverexperimentation.v1.TestConfig", RunTransform: s.transform}
return s.storer.RegisterTransformation(transformation)
}
func (s *Service) transform(config *experimentstore.ExperimentConfig) ([]*experimentation.Property, error) {
func (s *Service) transform(_ *experimentstore.ExperimentRun, config *experimentstore.ExperimentConfig) ([]*experimentation.Property, error) {
var experimentConfig = serverexperimentation.TestConfig{}
if err := ptypes.UnmarshalAny(config.Config, &experimentConfig); err != nil {
return []*experimentation.Property{}, err
......
......@@ -11,19 +11,12 @@ type ExperimentConfig struct {
Config *any.Any
}
func (ec *ExperimentConfig) CreateProperties(transformer *Transformer) ([]*experimentation.Property, error) {
properties, err := transformer.CreateProperties(ec)
if err != nil {
return nil, err
}
idProperty := []*experimentation.Property{
func (ec *ExperimentConfig) CreateProperties() ([]*experimentation.Property, error) {
return []*experimentation.Property{
{
Id: "config_identifier",
Label: "Config Identifier",
Value: &experimentation.Property_IntValue{IntValue: int64(ec.id)},
},
}
return append(idProperty, properties...), nil
}, nil
}
......@@ -5,17 +5,12 @@ import (
"github.com/golang/protobuf/ptypes/any"
"github.com/stretchr/testify/assert"
"go.uber.org/zap/zaptest"
experimentation "github.com/lyft/clutch/backend/api/chaos/experimentation/v1"
)
func TestConfigPropertiesWithNoRegisteredTransform(t *testing.T) {
logger := zaptest.NewLogger(t).Sugar()
transformer := NewTransformer(logger)
func TestConfigProperties(t *testing.T) {
config := &ExperimentConfig{id: 1, Config: &any.Any{}}
properties, err := config.CreateProperties(&transformer)
properties, err := config.CreateProperties()
assert := assert.New(t)
assert.NoError(err)
......@@ -23,31 +18,3 @@ func TestConfigPropertiesWithNoRegisteredTransform(t *testing.T) {
assert.Equal("config_identifier", properties[0].Id)
assert.Equal(int64(1), properties[0].GetIntValue())
}
func TestConfigPropertiesWithRegisteredTransform(t *testing.T) {
assert := assert.New(t)
transform := func(config *ExperimentConfig) ([]*experimentation.Property, error) {
return []*experimentation.Property{
{
Id: "foo",
Label: "bar",
Value: &experimentation.Property_StringValue{StringValue: "dar"},
},
}, nil
}
transformation := Transformation{ConfigTypeUrl: "type", ConfigTransform: transform}
logger := zaptest.NewLogger(t).Sugar()
transformer := NewTransformer(logger)
assert.NoError(transformer.Register(transformation))
config := &ExperimentConfig{id: 1, Config: &any.Any{TypeUrl: "type"}}
properties, err := config.CreateProperties(&transformer)
assert.NoError(err)
assert.Equal(2, len(properties))
assert.Equal("config_identifier", properties[0].Id)
assert.Equal(int64(1), properties[0].GetIntValue())
assert.Equal("foo", properties[1].Id)
assert.Equal("dar", properties[1].GetStringValue())
}
......@@ -10,16 +10,16 @@ import (
)
type ExperimentRun struct {
id uint64
startTime time.Time
endTime sql.NullTime
cancellationTime sql.NullTime
Id uint64
StartTime time.Time
EndTime sql.NullTime
CancellationTime sql.NullTime
creationTime time.Time
}
func (er *ExperimentRun) CreateProperties(now time.Time) ([]*experimentation.Property, error) {
status := timesToStatus(er.startTime, er.endTime, er.cancellationTime, now)
startTimeTimestamp, err := ptypes.TimestampProto(er.startTime)
status := timesToStatus(er.StartTime, er.EndTime, er.CancellationTime, now)
startTimeTimestamp, err := ptypes.TimestampProto(er.StartTime)
if err != nil {
return nil, err
}
......@@ -33,7 +33,7 @@ func (er *ExperimentRun) CreateProperties(now time.Time) ([]*experimentation.Pro
{
Id: "run_identifier",
Label: "Run Identifier",
Value: &experimentation.Property_IntValue{IntValue: int64(er.id)},
Value: &experimentation.Property_IntValue{IntValue: int64(er.Id)},
},
{
Id: "status",
......@@ -53,10 +53,10 @@ func (er *ExperimentRun) CreateProperties(now time.Time) ([]*experimentation.Pro
}
var time sql.NullTime
if er.endTime.Valid {
time = er.endTime
} else if er.cancellationTime.Valid {
time = er.cancellationTime
if er.EndTime.Valid {
time = er.EndTime
} else if er.CancellationTime.Valid {
time = er.CancellationTime
}
endTimeTimestamp, err := TimeToPropertyDateValue(time)
......@@ -70,7 +70,7 @@ func (er *ExperimentRun) CreateProperties(now time.Time) ([]*experimentation.Pro
Value: endTimeTimestamp,
})
cancelationTimeTimestamp, err := TimeToPropertyDateValue(er.cancellationTime)
cancelationTimeTimestamp, err := TimeToPropertyDateValue(er.CancellationTime)
if err != nil {
return nil, err
}
......
......@@ -23,7 +23,7 @@ func TestScheduledExperiment(t *testing.T) {
cancellation := sql.NullTime{Valid: false}
now := startTime.AddDate(0, 0, -1)
run := &ExperimentRun{id: 1, startTime: startTime, endTime: end, cancellationTime: cancellation, creationTime: creationTime}
run := &ExperimentRun{Id: 1, StartTime: startTime, EndTime: end, CancellationTime: cancellation, creationTime: creationTime}
config := &ExperimentConfig{id: 2, Config: &any.Any{}}
transformer := NewTransformer(logger)
......@@ -43,7 +43,7 @@ func TestCanceledExperiment(t *testing.T) {
Valid: true,
}
run := &ExperimentRun{id: 1, startTime: startTime, endTime: end, cancellationTime: cancellation, creationTime: creationTime}
run := &ExperimentRun{Id: 1, StartTime: startTime, EndTime: end, CancellationTime: cancellation, creationTime: creationTime}
config := &ExperimentConfig{id: 2, Config: &any.Any{}}
transformer := NewTransformer(logger)
......@@ -61,7 +61,7 @@ func TestRunningExperiment(t *testing.T) {
cancellation := sql.NullTime{Valid: false}
now := startTime.AddDate(0, 0, 1)
run := &ExperimentRun{id: 1, startTime: startTime, endTime: end, cancellationTime: cancellation, creationTime: creationTime}
run := &ExperimentRun{Id: 1, StartTime: startTime, EndTime: end, CancellationTime: cancellation, creationTime: creationTime}
config := &ExperimentConfig{id: 2, Config: &any.Any{}}
transformer := NewTransformer(logger)
......@@ -84,7 +84,7 @@ func TestStoppedExperiment(t *testing.T) {
Valid: true,
}
run := &ExperimentRun{id: 1, startTime: startTime, endTime: end, cancellationTime: cancellation, creationTime: creationTime}
run := &ExperimentRun{Id: 1, StartTime: startTime, EndTime: end, CancellationTime: cancellation, creationTime: creationTime}
config := &ExperimentConfig{id: 2, Config: &any.Any{}}
transformer := NewTransformer(logger)
......@@ -107,7 +107,7 @@ func TestCompletedExperiment(t *testing.T) {
}
now := endTime.AddDate(0, 0, 1)
run := &ExperimentRun{id: 1, startTime: startTime, endTime: end, cancellationTime: cancellation, creationTime: creationTime}
run := &ExperimentRun{Id: 1, StartTime: startTime, EndTime: end, CancellationTime: cancellation, creationTime: creationTime}
config := &ExperimentConfig{id: 2, Config: &any.Any{}}
transformer := NewTransformer(logger)
......
......@@ -8,8 +8,8 @@ import (
"github.com/stretchr/testify/assert"
)
func TestRunningRunPropertiesWithNoRegisteredTransform(t *testing.T) {
run := &ExperimentRun{id: 1, startTime: startTime, endTime: sql.NullTime{}, cancellationTime: sql.NullTime{}, creationTime: creationTime}
func TestRunningExperimentRunProperties(t *testing.T) {
run := &ExperimentRun{Id: 1, StartTime: startTime, EndTime: sql.NullTime{}, CancellationTime: sql.NullTime{}, creationTime: creationTime}
properties, err := run.CreateProperties(time.Now())
assert := assert.New(t)
......
......@@ -8,26 +8,32 @@ import (
)
func NewRunDetails(run *ExperimentRun, config *ExperimentConfig, transformer *Transformer, now time.Time) (*experimentation.ExperimentRunDetails, error) {
status := timesToStatus(run.startTime, run.endTime, run.cancellationTime, now)
status := timesToStatus(run.StartTime, run.EndTime, run.CancellationTime, now)
runProperties, err := run.CreateProperties(time.Now())
if err != nil {
return nil, err
}
configProperties, err := config.CreateProperties(transformer)
configProperties, err := config.CreateProperties()
if err != nil {
return nil, err
}
transformerProperties, err := transformer.CreateProperties(run, config)
if err != nil {
return nil, err
}
properties := append(runProperties, configProperties...)
properties = append(properties, transformerProperties...)
if err != nil {
return nil, err
}
return &experimentation.ExperimentRunDetails{
RunId: run.id,
RunId: run.Id,
Status: status,
Properties: &experimentation.PropertiesList{Items: properties},
Config: config.Config,
......
......@@ -7,24 +7,30 @@ import (
)
func NewRunListView(run *ExperimentRun, config *ExperimentConfig, transformer *Transformer, now time.Time) (*experimentation.ListViewItem, error) {
runProperties, err := run.CreateProperties(time.Now())
runProperties, err := run.CreateProperties(now)
if err != nil {
return nil, err
}
configProperties, err := config.CreateProperties(transformer)
configProperties, err := config.CreateProperties()
if err != nil {
return nil, err
}
transformerProperties, err := transformer.CreateProperties(run, config)
if err != nil {
return nil, err
}
properties := append(runProperties, configProperties...)
properties = append(properties, transformerProperties...)
propertiesMapItems := make(map[string]*experimentation.Property)
for _, p := range properties {
propertiesMapItems[p.Id] = p
}
return &experimentation.ListViewItem{
Identifier: run.id,
Id: run.Id,
Properties: &experimentation.PropertiesMap{Items: propertiesMapItems},
}, nil
}
package experimentstore
import (
"database/sql"
"testing"
"time"
"github.com/golang/protobuf/ptypes/any"
"github.com/stretchr/testify/assert"
"go.uber.org/zap/zaptest"
experimentation "github.com/lyft/clutch/backend/api/chaos/experimentation/v1"
)
func TestListViewRunningExperimentRunProperties(t *testing.T) {
startTime := time.Now()
expectedRun := &ExperimentRun{Id: 1, StartTime: startTime, EndTime: sql.NullTime{}, CancellationTime: sql.NullTime{}, creationTime: creationTime}
expectedConfig := &ExperimentConfig{id: 2, Config: &any.Any{TypeUrl: "foo"}}
expectedProperty := &experimentation.Property{
Id: "foo",
Label: "bar",
Value: &experimentation.Property_StringValue{StringValue: "dar"},
}
logger := zaptest.NewLogger(t).Sugar()
transformer := NewTransformer(logger)
transform := func(run *ExperimentRun, config *ExperimentConfig) ([]*experimentation.Property, error) {
assert.Equal(t, expectedRun, run)
assert.Equal(t, expectedConfig, config)
return []*experimentation.Property{expectedProperty}, nil
}
transformation := Transformation{ConfigTypeUrl: "foo", RunTransform: transform}
assert.NoError(t, transformer.Register(transformation))
listView, err := NewRunListView(expectedRun, expectedConfig, &transformer, time.Now())
assert.NoError(t, err)
assert.Equal(t, uint64(1), listView.Id)
assert.Equal(t, int64(1), listView.GetProperties().GetItems()["run_identifier"].GetIntValue())
assert.Equal(t, int64(2), listView.GetProperties().GetItems()["config_identifier"].GetIntValue())
assert.Equal(t, expectedProperty, listView.GetProperties().GetItems()["foo"])
}
......@@ -217,7 +217,7 @@ func (s *storer) GetListView(ctx context.Context) ([]*experimentation.ListViewIt
var details string
run := ExperimentRun{}
config := ExperimentConfig{Config: &any.Any{}}
err = rows.Scan(&run.id, &run.startTime, &run.endTime, &run.cancellationTime, &run.creationTime, &config.id, &details)
err = rows.Scan(&run.Id, &run.StartTime, &run.EndTime, &run.CancellationTime, &run.creationTime, &config.id, &details)
if err != nil {
return nil, err
}
......@@ -259,7 +259,7 @@ func (s *storer) GetExperimentRunDetails(ctx context.Context, id uint64) (*exper
var details string
run := ExperimentRun{}
config := ExperimentConfig{Config: &any.Any{}}
err := row.Scan(&run.id, &run.startTime, &run.endTime, &run.cancellationTime, &run.creationTime, &config.id, &details)
err := row.Scan(&run.Id, &run.StartTime, &run.EndTime, &run.CancellationTime, &run.creationTime, &config.id, &details)
if err != nil {
return nil, err
}
......
......@@ -9,34 +9,46 @@ import (
type Transformation struct {
ConfigTypeUrl string
ConfigTransform func(config *ExperimentConfig) ([]*experimentation.Property, error)
RunTransform func(run *ExperimentRun, config *ExperimentConfig) ([]*experimentation.Property, error)
}
type Transformer struct {
logger *zap.SugaredLogger
nameToConfigTransformMap map[string]*Transformation
logger *zap.SugaredLogger
nameToTransformMap map[string][]*Transformation
}
func NewTransformer(logger *zap.SugaredLogger) Transformer {
t := Transformer{logger, map[string]*Transformation{}}
t.nameToConfigTransformMap = map[string]*Transformation{}
t := Transformer{logger, map[string][]*Transformation{}}
t.nameToTransformMap = map[string][]*Transformation{}
return t
}
func (t *Transformer) Register(transformation Transformation) error {
t.nameToConfigTransformMap[transformation.ConfigTypeUrl] = &transformation
func (tr *Transformer) Register(transformation Transformation) error {
tr.nameToTransformMap[transformation.ConfigTypeUrl] = append(tr.nameToTransformMap[transformation.ConfigTypeUrl], &transformation)
return nil
}
func (t *Transformer) CreateProperties(config *ExperimentConfig) ([]*experimentation.Property, error) {
transform, exists := t.nameToConfigTransformMap[config.Config.TypeUrl]
func (tr *Transformer) CreateProperties(run *ExperimentRun, config *ExperimentConfig) ([]*experimentation.Property, error) {
transformations, exists := tr.nameToTransformMap[config.Config.TypeUrl]
if !exists {
return []*experimentation.Property{}, nil
}
properties, err := transform.ConfigTransform(config)
if err != nil {
t.logger.Errorw("error while creating properties", "error", err, "config", config)
var properties = []*experimentation.Property{}
for _, t := range transformations {
if t.RunTransform == nil {
continue
}
currentTransformationProperties, err := t.RunTransform(run, config)
if err != nil {
tr.logger.Errorw("error while creating properties from run and config",
"error", err, "config", config, "run", run)
return nil, err
}
properties = append(properties, currentTransformationProperties...)
}
return properties, err
return properties, nil
}
......@@ -10,39 +10,111 @@ import (
experimentation "github.com/lyft/clutch/backend/api/chaos/experimentation/v1"
)
func TestNoRegisteredTransform(t *testing.T) {
func TestNoRegisteredTransformation(t *testing.T) {
logger := zaptest.NewLogger(t).Sugar()
transformer := NewTransformer(logger)
config := &ExperimentConfig{id: 1, Config: &any.Any{}}
_, err := transformer.CreateProperties(config)
_, err := transformer.CreateProperties(&ExperimentRun{Id: 123}, config)
assert := assert.New(t)
assert.NoError(err)
assert.NoError(t, err)
}
func TestRegisteredTransform(t *testing.T) {
assert := assert.New(t)
func TestNoMatchingRegisteredRunConfigTransform(t *testing.T) {
logger := zaptest.NewLogger(t).Sugar()
transformer := NewTransformer(logger)
underlyingConfig := &any.Any{TypeUrl: "test"}
underlyingConfig := &any.Any{TypeUrl: "foo"}
config := &ExperimentConfig{id: 1, Config: underlyingConfig}
transform := func(run *ExperimentRun, config *ExperimentConfig) ([]*experimentation.Property, error) {
assert.FailNow(t, "not matching transform should not be called")
return []*experimentation.Property{}, nil
}
transformation := Transformation{ConfigTypeUrl: "bar", RunTransform: transform}
assert.NoError(t, transformer.Register(transformation))
properties, err := transformer.CreateProperties(&ExperimentRun{Id: 123}, config)
assert.NoError(t, err)
assert.Equal(t, 0, len(properties))
}
func TestMatchingRegisteredNullRunConfigTransform(t *testing.T) {
logger := zaptest.NewLogger(t).Sugar()
run := &ExperimentRun{Id: 123}
config := &ExperimentConfig{id: 1, Config: &any.Any{TypeUrl: "test"}}
transformation := Transformation{ConfigTypeUrl: "test"}
transformer := NewTransformer(logger)
assert.NoError(t, transformer.Register(transformation))
properties, err := transformer.CreateProperties(run, config)
assert.NoError(t, err)
assert.Equal(t, 0, len(properties))
}
func TestMatchingRegisteredRunConfigTransform(t *testing.T) {
logger := zaptest.NewLogger(t).Sugar()
expectedRun := &ExperimentRun{Id: 123}
expectedConfig := &ExperimentConfig{id: 1, Config: &any.Any{TypeUrl: "test"}}
expectedProperty := &experimentation.Property{
Id: "foo",
Label: "bar",
Value: &experimentation.Property_StringValue{StringValue: "dar"},
}
transform := func(config *ExperimentConfig) ([]*experimentation.Property, error) {
assert.Equal(underlyingConfig, config.Config)
transform := func(run *ExperimentRun, config *ExperimentConfig) ([]*experimentation.Property, error) {
assert.Equal(t, expectedRun, run)
assert.Equal(t, expectedConfig, config)
return []*experimentation.Property{expectedProperty}, nil
}
transformation := Transformation{ConfigTypeUrl: "test", ConfigTransform: transform}
transformation := Transformation{ConfigTypeUrl: "test", RunTransform: transform}
transformer := NewTransformer(logger)
assert.NoError(t, transformer.Register(transformation))
properties, err := transformer.CreateProperties(expectedRun, expectedConfig)
assert.NoError(t, err)
assert.Equal(t, 1, len(properties))
assert.Equal(t, expectedProperty, properties[0])
}
func TestMatchingMultipleRegisteredRunConfigTransforms(t *testing.T) {
logger := zaptest.NewLogger(t).Sugar()
expectedRun := &ExperimentRun{Id: 123}
expectedConfig := &ExperimentConfig{id: 1, Config: &any.Any{TypeUrl: "foo"}}
expectedProperty1 := &experimentation.Property{
Id: "foo1",
Label: "bar1",
Value: &experimentation.Property_StringValue{StringValue: "dar1"},
}
expectedProperty2 := &experimentation.Property{
Id: "foo2",
Label: "bar2",
Value: &experimentation.Property_StringValue{StringValue: "dar2"},
}
transform1 := func(run *ExperimentRun, config *ExperimentConfig) ([]*experimentation.Property, error) {
assert.Equal(t, expectedRun, run)
assert.Equal(t, expectedConfig, config)
return []*experimentation.Property{expectedProperty1}, nil
}
transform2 := func(run *ExperimentRun, config *ExperimentConfig) ([]*experimentation.Property, error) {
assert.Equal(t, expectedRun, run)
assert.Equal(t, expectedConfig, config)
return []*experimentation.Property{expectedProperty2}, nil
}
transformation1 := Transformation{ConfigTypeUrl: "foo", RunTransform: transform1}
transformation2 := Transformation{ConfigTypeUrl: "foo", RunTransform: transform2}
transformer := NewTransformer(logger)
assert.NoError(transformer.Register(transformation))
assert.NoError(t, transformer.Register(transformation1))
assert.NoError(t, transformer.Register(transformation2))
properties, err := transformer.CreateProperties(config)
assert.NoError(err)
assert.Equal(1, len(properties))
assert.Equal(expectedProperty, properties[0])
properties, err := transformer.CreateProperties(expectedRun, expectedConfig)
assert.NoError(t, err)
assert.Equal(t, 2, len(properties))
assert.Equal(t, []*experimentation.Property{expectedProperty1, expectedProperty2}, properties)
}
......@@ -3011,8 +3011,8 @@ export namespace clutch {
/** Properties of a ListViewItem. */
interface IListViewItem {
 
/** ListViewItem identifier */
identifier?: (number|Long|null);
/** ListViewItem id */
id?: (number|Long|null);
 
/** ListViewItem properties */
properties?: (clutch.chaos.experimentation.v1.IPropertiesMap|null);
......@@ -3027,8 +3027,8 @@ export namespace clutch {
*/
constructor(properties?: clutch.chaos.experimentation.v1.IListViewItem);
 
/** ListViewItem identifier. */
public identifier: (number|Long);
/** ListViewItem id. */
public id: (number|Long);
 
/** ListViewItem properties. */
public properties?: (clutch.chaos.experimentation.v1.IPropertiesMap|null);
......
......@@ -6908,7 +6908,7 @@ export const clutch = $root.clutch = (() => {
* Properties of a ListViewItem.
* @memberof clutch.chaos.experimentation.v1
* @interface IListViewItem
* @property {number|Long|null} [identifier] ListViewItem identifier
* @property {number|Long|null} [id] ListViewItem id
* @property {clutch.chaos.experimentation.v1.IPropertiesMap|null} [properties] ListViewItem properties
*/
 
......@@ -6928,12 +6928,12 @@ export const clutch = $root.clutch = (() => {
}
 
/**
* ListViewItem identifier.
* @member {number|Long} identifier
* ListViewItem id.
* @member {number|Long} id
* @memberof clutch.chaos.experimentation.v1.ListViewItem
* @instance
*/
ListViewItem.prototype.identifier = $util.Long ? $util.Long.fromBits(0,0,true) : 0;
ListViewItem.prototype.id = $util.Long ? $util.Long.fromBits(0,0,true) : 0;
 
/**
* ListViewItem properties.
......@@ -6954,9 +6954,9 @@ export const clutch = $root.clutch = (() => {
ListViewItem.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.identifier != null && message.hasOwnProperty("identifier"))
if (!$util.isInteger(message.identifier) && !(message.identifier && $util.isInteger(message.identifier.low) && $util.isInteger(message.identifier.high)))
return "identifier: integer|Long expected";
if (message.id != null && message.hasOwnProperty("id"))
if (!$util.isInteger(message.id) && !(message.id && $util.isInteger(message.id.low) && $util.isInteger(message.id.high)))
return "id: integer|Long expected";
if (message.properties != null && message.hasOwnProperty("properties")) {
let error = $root.clutch.chaos.experimentation.v1.PropertiesMap.verify(message.properties);
if (error)
......@@ -6977,15 +6977,15 @@ export const clutch = $root.clutch = (() => {
if (object instanceof $root.clutch.chaos.experimentation.v1.ListViewItem)
return object;
let message = new $root.clutch.chaos.experimentation.v1.ListViewItem();
if (object.identifier != null)
if (object.id != null)
if ($util.Long)
(message.identifier = $util.Long.fromValue(object.identifier)).unsigned = true;
else if (typeof object.identifier === "string")
message.identifier = parseInt(object.identifier, 10);
else if (typeof object.identifier === "number")
message.identifier = object.identifier;
else if (typeof object.identifier === "object")
message.identifier = new $util.LongBits(object.identifier.low >>> 0, object.identifier.high >>> 0).toNumber(true);
(message.id = $util.Long.fromValue(object.id)).unsigned = true;
else if (typeof object.id === "string")
message.id = parseInt(object.id, 10);
else if (typeof object.id === "number")
message.id = object.id;
else if (typeof object.id === "object")
message.id = new $util.LongBits(object.id.low >>> 0, object.id.high >>> 0).toNumber(true);
if (object.properties != null) {
if (typeof object.properties !== "object")
throw TypeError(".clutch.chaos.experimentation.v1.ListViewItem.properties: object expected");
......@@ -7010,16 +7010,16 @@ export const clutch = $root.clutch = (() => {
if (options.defaults) {
if ($util.Long) {
let long = new $util.Long(0, 0, true);
object.identifier = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
object.id = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
} else
object.identifier = options.longs === String ? "0" : 0;
object.id = options.longs === String ? "0" : 0;
object.properties = null;
}
if (message.identifier != null && message.hasOwnProperty("identifier"))
if (typeof message.identifier === "number")
object.identifier = options.longs === String ? String(message.identifier) : message.identifier;
if (message.id != null && message.hasOwnProperty("id"))
if (typeof message.id === "number")
object.id = options.longs === String ? String(message.id) : message.id;
else
object.identifier = options.longs === String ? $util.Long.prototype.toString.call(message.identifier) : options.longs === Number ? new $util.LongBits(message.identifier.low >>> 0, message.identifier.high >>> 0).toNumber(true) : message.identifier;
object.id = options.longs === String ? $util.Long.prototype.toString.call(message.id) : options.longs === Number ? new $util.LongBits(message.id.low >>> 0, message.id.high >>> 0).toNumber(true) : message.id;
if (message.properties != null && message.hasOwnProperty("properties"))
object.properties = $root.clutch.chaos.experimentation.v1.PropertiesMap.toObject(message.properties, options);
return object;
......@@ -30,7 +30,7 @@ const ListExperiments: React.FC<ListExperimentsProps> = ({ columns, links }) =>
const navigate = useNavigate();
const handleRowSelection = (event: any, item: IClutch.chaos.experimentation.v1.ListViewItem) => {
navigate(`/experimentation/run/${item.identifier}`);
navigate(`/experimentation/run/${item.id}`);
};
React.useEffect(() => {
......
......@@ -159,7 +159,7 @@ const ListView: React.FC<ListViewProps> = ({ columns, items, onRowSelection }) =
<TableRow
hover
onClick={event => handleClick(event, item)}
key={item.identifier.toString()}
key={item.id.toString()}
>
{columns &&
columns.map(column => {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment