diff options
10 files changed, 455 insertions, 1 deletions
diff --git a/deployment/zip/pom.xml b/deployment/zip/pom.xml index 86fcd2d7..7ba26ae5 100644 --- a/deployment/zip/pom.xml +++ b/deployment/zip/pom.xml @@ -120,6 +120,9 @@ fileset(dir: "${project.build.directory}/../../../products/target/script/", erroronmissingdir: false) + fileset(dir: + "${project.build.directory}/../../../profiles/target/script/", + erroronmissingdir: false) } ant.copy(todir: diff --git a/deployment/zip/src/main/release/conf/open-cli.properties b/deployment/zip/src/main/release/conf/open-cli.properties index de2e843d..27b592ab 100644 --- a/deployment/zip/src/main/release/conf/open-cli.properties +++ b/deployment/zip/src/main/release/conf/open-cli.properties @@ -44,7 +44,7 @@ cli.sample.gen.name=$s{env:OPEN_CLI_USECASE} cli.sample.gen.target=$s{env:OPEN_CLI_HOME}/open-cli-sample # mrkanag Move this to db, once exteranl command registration is supported in place of discovery -cli.schema.profile.available=http,snmp,cmd +cli.schema.profile.available=http,snmp,cmd,robot #other properties to load (it should be hanled when plugins are made as externally register-able #when command plugin management support is enabled in oclip diff --git a/profiles/pom.xml b/profiles/pom.xml index c978686f..90804ee9 100644 --- a/profiles/pom.xml +++ b/profiles/pom.xml @@ -35,6 +35,7 @@ <module>http</module> <module>snmp</module> <module>command</module> + <module>robot</module> </modules> <dependencies> diff --git a/profiles/robot/pom.xml b/profiles/robot/pom.xml new file mode 100644 index 00000000..0ecd447d --- /dev/null +++ b/profiles/robot/pom.xml @@ -0,0 +1,127 @@ +<?xml version="1.0"?> + +<!-- + Copyright 2020 Simran Singhal. + + 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. + --> + +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.onap.cli</groupId> + <artifactId>cli-profiles</artifactId> + <version>6.0.0-SNAPSHOT</version> + </parent> + + <artifactId>cli-profiles-robot</artifactId> + <name>cli/profiles/robot</name> + <packaging>jar</packaging> + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <!--Step-1:- SonarCloud migration from SonarQube --> + <sonar.language>java</sonar.language> + <sonar.surefire.reportsPath>${project.build.directory}/surefire-reports123</sonar.surefire.reportsPath> + <sonar.coverage.jacoco.xmlReportPaths>${project.reporting.outputDirectory}/jacoco-ut/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths> + <sonar.jacoco.reportMissing.force.zero>true</sonar.jacoco.reportMissing.force.zero> + <sonar.projectVersion>${project.version}</sonar.projectVersion> + <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis> + </properties> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.11</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.jmockit</groupId> + <artifactId>jmockit</artifactId> + <version>1.19</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.jmockit</groupId> + <artifactId>jmockit-coverage</artifactId> + <version>1.19</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.onap.cli</groupId> + <artifactId>cli-profiles-command</artifactId> + <version>${project.parent.version}</version> + </dependency> + </dependencies> + <build> + <plugins> + <!--Step-2:- SonarCloud migration from SonarQube --> + <plugin> + <groupId>org.jacoco</groupId> + <artifactId>jacoco-maven-plugin</artifactId> + <executions> + <execution> + <id>prepare-agent</id> + <goals> + <goal>prepare-agent</goal> + </goals> + </execution> + <execution> + <id>report</id> + <goals> + <goal>report</goal> + </goals> + <configuration> + <dataFile>${project.build.directory}/code-coverage/jacoco.exec</dataFile> + <outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <version>3.1.0</version> + <executions> + <execution> + <id>copy-resource-script</id> + <phase>validate</phase> + <goals> + <goal>copy-resources</goal> + </goals> + + <configuration> + <outputDirectory>../../profiles/target/script</outputDirectory> + <resources> + <resource> + <directory>${project.basedir}/src/main/resources/script</directory> + <includes> + <include>*.*</include> + </includes> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/profiles/robot/src/main/java/org/onap/cli/fw/robot/cmd/OnapRobotCommand.java b/profiles/robot/src/main/java/org/onap/cli/fw/robot/cmd/OnapRobotCommand.java new file mode 100644 index 00000000..fa995951 --- /dev/null +++ b/profiles/robot/src/main/java/org/onap/cli/fw/robot/cmd/OnapRobotCommand.java @@ -0,0 +1,44 @@ +/* + * Copyright 2020 Simran Singhal. + * + * 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. + */ + +package org.onap.cli.fw.robot.cmd; + +import java.util.List; +import java.util.Map; + +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cli.fw.cmd.cmd.OpenCommandShellCmd; +import org.onap.cli.fw.robot.conf.OnapCommandRobotConstants; +import org.onap.cli.fw.robot.schema.OnapCommandSchemaRobotLoader; +import org.onap.cli.fw.error.OnapCommandException; + +/** + * Oclip robot Command. + * + */ +@OnapCommandSchema(type = OnapCommandRobotConstants.ROBOT_SCHEMA_PROFILE) +public class OnapRobotCommand extends OpenCommandShellCmd { + + public OnapRobotCommand() { + super.addDefaultSchemas(OnapCommandRobotConstants.DEFAULT_PARAMETER_ROBOT_FILE_NAME); + } + + @Override + protected List<String> initializeProfileSchema(Map<String, ?> schemaMap, boolean validate) throws OnapCommandException { + return OnapCommandSchemaRobotLoader.parseRobotSchema(this, schemaMap, validate); + } + +}
\ No newline at end of file diff --git a/profiles/robot/src/main/java/org/onap/cli/fw/robot/conf/OnapCommandRobotConstants.java b/profiles/robot/src/main/java/org/onap/cli/fw/robot/conf/OnapCommandRobotConstants.java new file mode 100644 index 00000000..9aac11e7 --- /dev/null +++ b/profiles/robot/src/main/java/org/onap/cli/fw/robot/conf/OnapCommandRobotConstants.java @@ -0,0 +1,34 @@ +/* + * Copyright 2020 Simran Singhal. + * + * 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. + */ + +package org.onap.cli.fw.robot.conf; + +/** + * OnapCommandRobotConstants. + * + */ +public class OnapCommandRobotConstants { + public static final String ROBOT_SCHEMA_PROFILE = "robot"; + public static final String ROBOT = "robot"; + + public static final String DEFAULT_PARAMETER_ROBOT_FILE_NAME = "default_input_parameters_robot.yaml"; + + private OnapCommandRobotConstants() { + //as per coding standard ! + } +} + + diff --git a/profiles/robot/src/main/java/org/onap/cli/fw/robot/schema/OnapCommandSchemaRobotLoader.java b/profiles/robot/src/main/java/org/onap/cli/fw/robot/schema/OnapCommandSchemaRobotLoader.java new file mode 100644 index 00000000..3b75b504 --- /dev/null +++ b/profiles/robot/src/main/java/org/onap/cli/fw/robot/schema/OnapCommandSchemaRobotLoader.java @@ -0,0 +1,109 @@ +/* + * Copyright 2020 Simran Singhal. + * + * 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. + */ + +package org.onap.cli.fw.robot.schema; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.onap.cli.fw.robot.cmd.OnapRobotCommand; +import org.onap.cli.fw.robot.conf.OnapCommandRobotConstants; +import org.onap.cli.fw.cmd.conf.OnapCommandCmdConstants; +import org.onap.cli.fw.conf.OnapCommandConfig; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.utils.OnapCommandUtils; +import java.util.stream.Collectors; + +public class OnapCommandSchemaRobotLoader { + + private OnapCommandSchemaRobotLoader() { + // to follow standards ! + } + + /** + * Load the schema. + * + * @param robot + * OnapRobotCommand + * @param schemaName + * schema name + * @throws OnapCommandException + * on error + */ + public static List<String> parseRobotSchema(OnapRobotCommand robot, + final Map<String, ?> values, + boolean validate) throws OnapCommandException { //NOSONAR + ArrayList<String> errorList = new ArrayList<>(); + Map<String, ?> valMap = (Map<String, ?>) values.get(OnapCommandRobotConstants.ROBOT); + + if (valMap != null) { + if (validate) { + OnapCommandUtils.validateTags(errorList, valMap, OnapCommandConfig.getCommaSeparatedList(OnapCommandCmdConstants.CMD_SECTIONS), + OnapCommandConfig.getCommaSeparatedList(OnapCommandCmdConstants.CMD_MANDATORY_SECTIONS), OnapCommandRobotConstants.ROBOT); + } + for (Map.Entry<String, ?> entry1 : valMap.entrySet()) { + String key1 = entry1.getKey(); + + switch (key1) { + case OnapCommandCmdConstants.COMMAND: + Object o = valMap.get(key1); + if (o instanceof List) { + robot.setCommand((List<String>) o); + } else { + robot.setCommand(Arrays.asList((String) o)); + } + break; + + case OnapCommandCmdConstants.ENVIRONMENT: + Map<String, String> envMap = (Map<String, String>) valMap.get(key1); + robot.setEnvs(envMap); + break; + + case OnapCommandCmdConstants.WD: + robot.setWd((String)valMap.get(key1)); + break; + + case OnapCommandCmdConstants.OUTPUT: + robot.setOutput((String)valMap.get(key1)); + break; + + case OnapCommandCmdConstants.ERROR: + robot.setError((String)valMap.get(key1)); + break; + + case OnapCommandCmdConstants.RESULT_MAP: + robot.setResultMap((Map<String, String>) valMap.get(key1)); + break; + + case OnapCommandCmdConstants.SUCCESS_EXIT_CODE: + List<String> list = (ArrayList) valMap.get(key1); + robot.setSuccessStatusCodes(list.stream().map(s -> Integer.parseInt(s)).collect(Collectors.toList())); + break; + + case OnapCommandCmdConstants.PASS_CODE: + robot.setPassCodes((ArrayList) valMap.get(key1)); + break; + default : // Do nothing + } + } + } + + return errorList; + } + +}
\ No newline at end of file diff --git a/profiles/robot/src/main/resources/META-INF/services/org.onap.cli.fw.cmd.OnapCommand b/profiles/robot/src/main/resources/META-INF/services/org.onap.cli.fw.cmd.OnapCommand new file mode 100644 index 00000000..f69721e2 --- /dev/null +++ b/profiles/robot/src/main/resources/META-INF/services/org.onap.cli.fw.cmd.OnapCommand @@ -0,0 +1,15 @@ +# Copyright 2020 Simran Singhal. +# +# 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. + +org.onap.cli.fw.robot.cmd.OnapRobotCommand
\ No newline at end of file diff --git a/profiles/robot/src/main/resources/open-cli-schema/robot/default_input_parameters_robot.yaml b/profiles/robot/src/main/resources/open-cli-schema/robot/default_input_parameters_robot.yaml new file mode 100644 index 00000000..31687a74 --- /dev/null +++ b/profiles/robot/src/main/resources/open-cli-schema/robot/default_input_parameters_robot.yaml @@ -0,0 +1,37 @@ +# Copyright 2020 Simran Singhal. +# +# 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. + +open_cli_schema_version: 1.0 + +parameters: + - name: variables-file-path + description: Variables file path + type: string + short_option: x + long_option: variables-file-path + is_optional: true + default_value: '' + - name: api-tests-folder-path + type: string + description: Location to api-tests folder + short_option: l + long_option: api-tests-folder-path + is_optional: false + - name: format + type: string + description: Output formats, supported formats such as table, csv, json, yaml + short_option: f + long_option: format + default_value: text + is_default_param: true
\ No newline at end of file diff --git a/profiles/robot/src/main/resources/script/run-robot-testcase.py b/profiles/robot/src/main/resources/script/run-robot-testcase.py new file mode 100644 index 00000000..9fe0f607 --- /dev/null +++ b/profiles/robot/src/main/resources/script/run-robot-testcase.py @@ -0,0 +1,84 @@ +#!/usr/bin/python +# Copyright 2020 Simran Singhal. +# +# 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. + +import os +import argparse +import uuid +from robot import run +from argparse import RawTextHelpFormatter + +def execute_robot_run(request_id, test_suite, testcase, variables_file_path): + output_dir = os.getenv('OPEN_CLI_HOME') + '/data/executions/' + request_id + '/logs' + + with open('run.txt', 'w') as output: + if(variables_file_path): + run(test_suite, report=None, log=None, test=testcase, variablefile=variables_file_path, stdout=output, stderr=output, outputdir=output_dir) + else: + run(test_suite, report=None, log=None, test=testcase, stdout=output, stderr=output, outputdir=output_dir) + + if os.path.exists('run.txt'): + with open('run.txt', 'r') as log: + print(log.read()) + os.remove('run.txt') + +def main(): + text = 'This command helps to run a robot testcase\n' \ + 'These python modules are need to be installed for running the tests\n' \ + 'robotframework==3.1\n' \ + 'RESTinstance==1.0.0rc4\n' \ + 'robotframework-dependencylibrary==1.0.0.post1\n' \ + 'robotframework-jsonlibrary==0.3\n' \ + 'robotframework-jsonschemalibrary==1.0\n' \ + 'robotframework-mockserver==0.0.4\n' + + parser = argparse.ArgumentParser(description=text, formatter_class=RawTextHelpFormatter) + parser.add_argument('--request-id', action='store', dest='request_id', + help='Request Id to track the progress of running this script', + default=os.environ.get('OPEN_CLI_REQUEST_ID')) + parser.add_argument('--test-suite', action='store', dest='test_suite', + help='Location to test suite file', required=True) + parser.add_argument('--testcase', action='store', dest='testcase', + help='Name of the testcase', required=True, nargs='+') + parser.add_argument('--variables-file-path', action='store', dest='variables_file_path', + help='Location to variable file', nargs='?', const='') + + args = parser.parse_args() + + request_id = args.request_id + test_suite = args.test_suite + testcase = ' '.join(args.testcase) + variables_file_path = '' + + if not request_id: + request_id = str(uuid.uuid4()) + + if args.variables_file_path: + variables_file_path = args.variables_file_path + + if os.path.exists(variables_file_path): + + if not os.path.isfile(variables_file_path): + raise Exception('Given variable file path is not a file\n') + + else: + raise Exception('Given variable file path does not exist\n') + + if not os.path.exists(test_suite): + raise Exception('Given api-tests folder location does not exist\n') + + execute_robot_run(request_id,test_suite, testcase, variables_file_path) + +if __name__ == '__main__': + main() |