Skip to content

Commit

Permalink
Add ValueProviderFactory, ListElementValueProvider and FormattedStrin…
Browse files Browse the repository at this point in the history
…gValueProvider. (#1168)

Signed-off-by: Aastha Bist <[email protected]>
  • Loading branch information
bistaastha authored Nov 11, 2021
1 parent 6d5f071 commit 14bbbcb
Show file tree
Hide file tree
Showing 10 changed files with 757 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

const ValueProviderInterface = require('./value-provider-interface');
/**
* Value class provider for formatted strings based on other value providers.
*/
class FormattedStringValueProvider extends ValueProviderInterface {
/**
* Initialize an instance of FormattedStringValueProvider
* @param {object} options The user provided options for value provider
* @param {object} variables Store of variables managed by workload module
* @param {object} parameters Store of workload parameters provided by the user through the round configuration
* @param {object} valueProviderFactory ValueProviderFactory object reference
*/
constructor(options, variables, parameters, valueProviderFactory) {
super(options, variables, parameters, valueProviderFactory);

if (this.options === undefined) {
throw new Error(`Incorrect options value: ${this.options}`);
}

if (this.valueProviderFactory === undefined) {
throw new Error(`Incorrect valueProviderFactory value: ${this.valueProviderFactory}`);
}

if (
this.options.format === undefined ||
typeof this.options.format !== 'string'
) {
throw new Error(`Invalid format value: ${this.options.format}`);
}

if (!Array.isArray(this.options.parts)) {
throw new Error(`Incorrect parts value: ${this.options.parts}`);
}

this.format = this.options.format;
this.parts = this.options.parts;
const partLength = this.parts.length;
this.subproviders = [];

let regExp = new RegExp('[{][1-9]+[0-9]*[}]', 'g');
let matches = this.format.match(regExp) || [];
this.indexRegexPatterns = new Array(partLength).fill(-1);

for(const match of matches) {
const subMatch = match.slice(1, -1);
const index = Number(subMatch);
if (index < 1 || index > partLength) {
throw new Error(`Out of bound placeholder in format string: ${index}. Must be in range [1,${partLength}]`);
}
this.indexRegexPatterns[index - 1] = new RegExp(`\\{${subMatch}\\}`, 'g'); // regexp({01})
}

this.indexRegexPatterns.forEach((value, index) => {
if (value === -1) {
// TODO: convert to warning later
throw new Error(`Missing {${index + 1}} placeholder for subprovider`);
}
});

this.parts.forEach((element) => {
const subprovider = this.valueProviderFactory.createValueProvider(
element.type,
element.options
);
this.subproviders.push(subprovider);
});
}
/**
* Generates value for corresponding parameter
* @returns {string} value for parameter according to options.name
*/
generateValue() {
let result = `${this.format}`;

this.subproviders.forEach((subprovider, index) => {
const value = subprovider.generateValue();
result = result.replace(this.indexRegexPatterns[index], value);
});
return result;
}
}

module.exports = FormattedStringValueProvider;
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

const ValueProviderInterface = require('./value-provider-interface');

/**
* Class with implementation of ListElementValueProvider
*/
class ListElementValueProvider extends ValueProviderInterface {
/**
* Initialize an instance of ListElementValueProvider
* @param {object} options The user provided options for value provider
* @param {object} variables Store of variables managed by workload module
* @param {object} parameters Store of workload parameters provided by the user through the round configuration
* @param {object} valueProviderFactory ValueProviderFactory object reference
*/
constructor(options, variables, parameters, valueProviderFactory) {
super(options, variables, parameters, valueProviderFactory);

if(this.options === undefined) {
throw new Error(`Incorrect options value: ${this.options}`);
}

if(this.valueProviderFactory === undefined){
throw new Error('Missing factory for list element value provider');
}

if(this.options.list === undefined || !Array.isArray(this.options.list)) {
throw new Error(`Incorrect value for list: ${this.options.list}`);
}

if(this.options.list.length === 0){
throw new Error('Empty list not allowed in List element value provider');
}

if(this.options.selector === undefined || typeof this.options.selector !== 'object') {
throw new Error(`Incorrect value for selector: ${this.options.selector}`);
}

this.list = this.options.list;

this.selector = this.valueProviderFactory.createValueProvider(this.options.selector.type, this.options.selector.options);
}
/**
* Returns value for corresponding variable/parameter value from the list
* @returns {any} value for parameter according to options.name
*/
generateValue() {
return this.list[this.selector.generateValue() % this.list.length];
}
}

module.exports = ListElementValueProvider;
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ const ValueProviderInterface = require('./value-provider-interface');
class ParameterReferenceValueProvider extends ValueProviderInterface {
/**
* Initialize an instance of ParameterReferenceValueProvider
* @param {object} options Options for configured parameter generation
* @param {object} variables Caliper provided variables
* @param {object} parameters User provided variables
* @param {object} options The user provided options for value provider
* @param {object} variables Store of variables managed by workload module
* @param {object} parameters Store of workload parameters provided by the user through the round configuration
* @param {object} valueProviderFactory ValueProviderFactory object reference
*/
constructor(options, variables, parameters, valueProviderFactory) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ const ValueProviderInterface = require('./value-provider-interface');
class UniformRandomValueProvider extends ValueProviderInterface {
/**
* Initialize an instance of UniformRandomValueProvider
* @param {object} options Options for configured parameter generation
* @param {object} variables Caliper provided variables
* @param {object} parameters User provided variables
* @param {object} options The user provided options for value provider
* @param {object} variables Store of variables managed by workload module
* @param {object} parameters Store of workload parameters provided by the user through the round configuration
* @param {object} valueProviderFactory ValueProviderFactory object reference
*/
constructor(options, variables, parameters, valueProviderFactory) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

const VariableReferenceValueProvider = require('./variable-reference-value-provider');
const ParameterReferenceValueProvider = require('./parameter-reference-value-provider');
const FormattedStringValueProvider = require('./formatted-string-value-provider');
const ListElementValueProvider = require('./list-element-value-provider');
const UniformRandomValueProvider = require('./uniform-random-value-provider');

/**
* Factory class for transparently creating value provider instances
* based on user configurations.
*/
class ValueProviderFactory {
/**
* Initialize an instance of ValueProviderFactory
* @param {object} variables Store of variables managed by workload module
* @param {object} parameters Store of workload parameters provided by the user through the round configuration
*/
constructor(variables, parameters) {
this.variables = variables;
this.parameters = parameters;
}
/**
* Creates and returns a new instance of value provider based on provided parameters
* @param {object} type The type of value provider to create
* @param {object} options The user-provided options for the value provider
* @returns {object} Returns the crated ValueProviderInterface
*/
createValueProvider(type, options) {
if (type === undefined) {
throw new Error(`Invalid value for type: ${typeof type}`);
}

let ValueProviderType;
switch(type) {
case 'variable_reference':
ValueProviderType = VariableReferenceValueProvider;
break;

case 'parameter_reference':
ValueProviderType = ParameterReferenceValueProvider;
break;

case 'formatted_string':
ValueProviderType = FormattedStringValueProvider;
break;

case 'list_element':
ValueProviderType = ListElementValueProvider;
break;

case 'uniform_random':
ValueProviderType = UniformRandomValueProvider;
break;

default:
throw new Error(`Unknown value provider type: ${type}`);
}

return new ValueProviderType(
options,
this.variables,
this.parameters,
this
);
}
}

module.exports = ValueProviderFactory;
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
class ValueProviderInterface {
/**
* Initialize an instance of ValueProviderInterface
* @param {object} options Options for configured parameter generation
* @param {object} variables Caliper provided variables
* @param {object} parameters User provided variables
* @param {object} options The user provided options for value provider
* @param {object} variables Store of variables managed by workload module
* @param {object} parameters Store of workload parameters provided by the user through the round configuration
* @param {object} valueProviderFactory ValueProviderFactory object reference
*/
constructor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ const ValueProviderInterface = require('./value-provider-interface');
class VariableReferenceValueProvider extends ValueProviderInterface {
/**
* Initialize an instance of VariableReferenceValueProvider
* @param {object} options Options for configured parameter generation
* @param {object} variables Caliper provided variables
* @param {object} parameters User provided variables
* @param {object} options The user provided options for value provider
* @param {object} variables Store of variables managed by workload module
* @param {object} parameters Store of workload parameters provided by the user through the round configuration
* @param {object} valueProviderFactory ValueProviderFactory object reference
*/
constructor(options, variables, parameters, valueProviderFactory) {
Expand Down
Loading

0 comments on commit 14bbbcb

Please sign in to comment.