aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmso-robot/.gitignore8
-rw-r--r--cmso-robot/docker/Dockerfile52
-rw-r--r--cmso-robot/docker/lighttpd.conf27
-rw-r--r--cmso-robot/ete.sh20
-rw-r--r--cmso-robot/red.xml61
-rw-r--r--cmso-robot/robot/assets/get_schedule_UUIDs.txt7
-rw-r--r--cmso-robot/robot/assets/sql/InitDB.sql3
-rw-r--r--cmso-robot/robot/assets/sql/OptimizationInProgresss.sql3
-rw-r--r--cmso-robot/robot/assets/sql/VericaQueries.sql9
-rw-r--r--cmso-robot/robot/assets/sql/clearthetable.sql11
-rw-r--r--cmso-robot/robot/assets/sql/demo.sql11
-rw-r--r--cmso-robot/robot/assets/sql/searchSQL.sql20
-rw-r--r--cmso-robot/robot/assets/sql/selectDetails.sql4
-rw-r--r--cmso-robot/robot/assets/sql/selectall.sql9
-rw-r--r--cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyDomain.json.template30
-rw-r--r--cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyScheduleID.json.template30
-rw-r--r--cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyScheduleName.json.template30
-rw-r--r--cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyUserID.json.template30
-rw-r--r--cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowIncorrectPolicyId.json.template30
-rw-r--r--cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowIncorrectWorkflow.json.template30
-rw-r--r--cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNegativeNormalDurationInSeconds.json.template30
-rw-r--r--cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNoEndTime.json.template30
-rw-r--r--cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNoNodeName.json.template30
-rw-r--r--cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNoStartTime.json.template30
-rw-r--r--cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowSwitchedTime.json.template30
-rw-r--r--cmso-robot/robot/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyAdditionalDuration.json.template23
-rw-r--r--cmso-robot/robot/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyDomain.json.template23
-rw-r--r--cmso-robot/robot/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyScheduleId.json.template23
-rw-r--r--cmso-robot/robot/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyUserId.json.template23
-rw-r--r--cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyDomain.json.template20
-rw-r--r--cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyScheduleId.json.template20
-rw-r--r--cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyScheduleName.json.template23
-rw-r--r--cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptySchedulingInfo.json.template14
-rw-r--r--cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyUserId.json.template14
-rw-r--r--cmso-robot/robot/assets/templates/changemanagement/MultipleVnfImmediate.json.template24
-rw-r--r--cmso-robot/robot/assets/templates/changemanagement/OneGroupMultipleVNFsOneChangeWindow.json.template32
-rw-r--r--cmso-robot/robot/assets/templates/changemanagement/OneGroupMultipleVNSsTwoChangeWindows.json.template37
-rw-r--r--cmso-robot/robot/assets/templates/changemanagement/OneVnfImmediate.json.template25
-rw-r--r--cmso-robot/robot/assets/templates/changemanagement/OneVnfImmediateIncorrectWorkflow.json.template21
-rw-r--r--cmso-robot/robot/assets/templates/changemanagement/OneVnfImmediateReplaceVNFInfra.json.template23
-rw-r--r--cmso-robot/robot/assets/templates/changemanagement/OneVnfOneChangeWindow.json.template30
-rw-r--r--cmso-robot/robot/assets/templates/changemanagement/OneVnfOneChangeWindowEmptyCallbackData.json.template25
-rw-r--r--cmso-robot/robot/assets/templates/changemanagement/OneVnfOneChangeWindowEmptyCallbackURL.json.template30
-rw-r--r--cmso-robot/robot/assets/templates/changemanagement/OneVnfOneChangeWindowReplaceVNFInfra.json.template30
-rw-r--r--cmso-robot/robot/assets/templates/changemanagement/VidCallbackData.json.template40
-rw-r--r--cmso-robot/robot/assets/test_properties.py41
-rw-r--r--cmso-robot/robot/locallibrary/cmsoUtils/CurlLibrary.py13
-rw-r--r--cmso-robot/robot/locallibrary/cmsoUtils/HTTPUtils.py21
-rw-r--r--cmso-robot/robot/locallibrary/cmsoUtils/JSONUtils.py37
-rw-r--r--cmso-robot/robot/locallibrary/cmsoUtils/OSUtils.py14
-rw-r--r--cmso-robot/robot/locallibrary/cmsoUtils/RequestsClientCert.py7
-rw-r--r--cmso-robot/robot/locallibrary/cmsoUtils/StringTemplater.py8
-rw-r--r--cmso-robot/robot/locallibrary/cmsoUtils/UUID.py8
-rw-r--r--cmso-robot/robot/resources/browser_setup.robot50
-rw-r--r--cmso-robot/robot/resources/files.robot50
-rw-r--r--cmso-robot/robot/resources/json_templater.robot20
-rw-r--r--cmso-robot/robot/resources/misc.robot42
-rw-r--r--cmso-robot/robot/resources/scheduler_common.robot85
-rw-r--r--cmso-robot/robot/resources/scheduler_requests/approval_requests.robot36
-rw-r--r--cmso-robot/robot/resources/scheduler_requests/create_schedule.robot49
-rw-r--r--cmso-robot/robot/resources/test_templates/change_management.robot166
-rw-r--r--cmso-robot/robot/resources/test_templates/change_management_ete.robot84
-rw-r--r--cmso-robot/robot/resources/test_templates/check_logs.robot95
-rw-r--r--cmso-robot/robot/resources/vtm_common.robot93
-rw-r--r--cmso-robot/robot/testsuites/ChangeManagementCancel.robot24
-rw-r--r--cmso-robot/robot/testsuites/ChangeManagementDBFailover.robot25
-rw-r--r--cmso-robot/robot/testsuites/ChangeManagementFailure.robot57
-rw-r--r--cmso-robot/robot/testsuites/ChangeManagementFuture.robot24
-rw-r--r--cmso-robot/robot/testsuites/ChangeManagementImmediate.robot27
-rw-r--r--cmso-robot/robot/testsuites/ChangeManagementImmediateFailure.robot52
-rw-r--r--cmso-robot/robot/testsuites/ChangeManagementRejection.robot18
-rw-r--r--cmso-robot/robot/testsuites/CheckLog.robot39
-rw-r--r--cmso-robot/robot/testsuites/CheckScheduleStatus.robot18
-rw-r--r--cmso-robot/robot/testsuites/MiscTests.robot23
-rw-r--r--cmso-robot/robot/testsuites/VtmAccess.robot105
-rw-r--r--cmso-robot/runVtmCleanup.sh10
-rw-r--r--cmso-robot/setup.sh60
77 files changed, 2476 insertions, 0 deletions
diff --git a/cmso-robot/.gitignore b/cmso-robot/.gitignore
new file mode 100644
index 0000000..44bdbba
--- /dev/null
+++ b/cmso-robot/.gitignore
@@ -0,0 +1,8 @@
+/log.html
+/output.xml
+/report.html
+/selenium-screenshot-*.png
+*.pyc
+/libspecs/
+/geckodriver.log
+/robot/library/ \ No newline at end of file
diff --git a/cmso-robot/docker/Dockerfile b/cmso-robot/docker/Dockerfile
new file mode 100644
index 0000000..3e0a917
--- /dev/null
+++ b/cmso-robot/docker/Dockerfile
@@ -0,0 +1,52 @@
+FROM dockercentral.it.att.com:5300/library/ubuntu:16.04
+## Be careful of Windows newlines
+
+MAINTAINER "Scheduler"
+
+LABEL name="Docker image for the Scheduler Robot Testing Framework"
+LABEL usage="docker run -e <testname> scheduler_robot
+
+# Install Python Pip, Robot framework, firefox, lighttpd web server, wget
+RUN apt-get update
+RUN apt-get --assume-yes upgrade
+RUN apt-get --assume-yes install python2.7
+RUN apt-get --assume-yes install build-essential
+RUN apt-get --assume-yes install dbus
+RUN apt-get --assume-yes install dnsutils
+RUN apt-get --assume-yes install git
+RUN apt-get --assume-yes install libappindicator1
+RUN apt-get --assume-yes install libffi-dev
+RUN apt-get --assume-yes install libindicator7
+RUN apt-get --assume-yes install libssl-dev
+RUN apt-get --assume-yes install libxss1
+RUN apt-get --assume-yes install lighttpd
+RUN apt-get --assume-yes install net-tools
+RUN apt-get --assume-yes install python-dev
+RUN apt-get --assume-yes install python-pip
+RUN apt-get --assume-yes install unzip
+RUN apt-get --assume-yes install wget
+RUN apt-get --assume-yes install xvfb
+RUN pip install --upgrade pip
+RUN pip install robotframework
+RUN python --version
+
+# Install chrome
+RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \
+ echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list && \
+ apt-get update && \
+ apt-get --assume-yes install google-chrome-stable
+
+# Copy the robot code
+
+COPY / /opt/app/scheduler_robot/
+COPY docker/lighttpd.conf /etc/lighttpd/lighttpd.conf
+RUN ls -ltr /opt/app/scheduler_robot
+RUN chmod 777 /opt/app/scheduler_robot/setup.sh
+
+# Update the ssh library so that it will run properly in the docker env
+RUN cd /opt/app/scheduler_robot/ && ./setup.sh && apt-get clean
+
+###CMD ["lighttpd", "-D", "-f", "/etc/lighttpd/lighttpd.conf"]
+
+
+
diff --git a/cmso-robot/docker/lighttpd.conf b/cmso-robot/docker/lighttpd.conf
new file mode 100644
index 0000000..5cd4d9a
--- /dev/null
+++ b/cmso-robot/docker/lighttpd.conf
@@ -0,0 +1,27 @@
+server.document-root = "/opt/app/testsuite/html/"
+
+server.port = 88
+
+server.username = "www-data"
+server.groupname = "www-data"
+
+dir-listing.activate = "disable"
+
+mimetype.assign = (
+ ".html" => "text/html"
+)
+
+static-file.exclude-extensions = ( ".fcgi", ".php", ".rb", "~", ".inc", ".cgi" )
+index-file.names = ( "index.html" )
+
+server.modules += ( "mod_auth" )
+auth.debug = 2
+auth.backend = "plain"
+auth.backend.plain.userfile = "/etc/lighttpd/authorization"
+auth.require = ( "/" =>
+(
+"method" => "basic",
+"realm" => "Password protected area",
+"require" => "valid-user"
+)
+)
diff --git a/cmso-robot/ete.sh b/cmso-robot/ete.sh
new file mode 100644
index 0000000..084f9ca
--- /dev/null
+++ b/cmso-robot/ete.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+#
+ROBOT_CMD="python -m robot.run"
+ROBOT_HOME=`pwd`
+ROBOT_PATH=${ROBOT_PATH}:${ROBOT_HOME}/robot/library
+ROBOT_PATH=${ROBOT_PATH}:${ROBOT_HOME}/robot/locallibrary/cmsoUtils
+VARIABLE_FILES="${VARIABLE_FILES} -V ${ROBOT_HOME}/robot/assets/test_properties.py"
+
+VARIABLES="${VARIABLES} -v GLOBAL_VID_USERID:${GLOBAL_VID_USERID}"
+VARIABLES="${VARIABLES} -v GLOBAL_SCHEDULER_HOST:${GLOBAL_SCHEDULER_HOST}"
+VARIABLES="${VARIABLES} -v GLOBAL_SCHEDULER_PORT:${GLOBAL_SCHEDULER_PORT}"
+VARIABLES="${VARIABLES} -v GLOBAL_SCHEDULER_USER:${GLOBAL_SCHEDULER_USER}"
+VARIABLES="${VARIABLES} -v GLOBAL_SCHEDULER_PASSWORD:${GLOBAL_SCHEDULER_PASSWORD}"
+VARIABLES="${VARIABLES} -v GLOBAL_SCHEDULER_PROTOCOL:${GLOBAL_SCHEDULER_PROTOCOL}"
+
+HTTP_PROXY=
+HTTPS_PROXY=
+
+${ROBOT_CMD} ${OUTPUT} -P ${ROBOT_PATH} ${VARIABLE_FILES} ${VARIABLES} ${TAGS} ${ROBOT_HOME}
+
diff --git a/cmso-robot/red.xml b/cmso-robot/red.xml
new file mode 100644
index 0000000..368d2e8
--- /dev/null
+++ b/cmso-robot/red.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ Copyright © 2017-2018 AT&T Intellectual Property.
+ Modifications Copyright © 2018 IBM.
+
+ 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.
+
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ 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.
+-->
+
+<projectConfiguration>
+ <configVersion>1.0</configVersion>
+ <robotExecEnvironment path="C:\Python27"/>
+ <relativeTo>PROJECT</relativeTo>
+ <referencedLibrary type="PYTHON" name="PycURLLibrary" path="SchedulerRobot/robot/library"/>
+ <referencedLibrary type="PYTHON" name="RequestsLibrary" path="SchedulerRobot/robot/library"/>
+ <referencedLibrary type="PYTHON" name="Selenium2Library" path="SchedulerRobot/robot/library"/>
+ <referencedLibrary type="PYTHON" name="selenium" path="SchedulerRobot/robot/library"/>
+ <referencedLibrary type="PYTHON" name="SSHLibrary" path="SchedulerRobot/robot/library"/>
+ <referencedLibrary type="PYTHON" name="HttpLibrary" path="SchedulerRobot/robot/library"/>
+ <referencedLibrary type="PYTHON" name="HttpLibrary.HTTP" path="SchedulerRobot/robot/library"/>
+ <referencedLibrary type="PYTHON" name="StringTemplater" path="SchedulerRobot/robot/locallibrary/cmsoUtils"/>
+ <referencedLibrary type="PYTHON" name="UUID" path="SchedulerRobot/robot/locallibrary/cmsoUtils"/>
+ <referencedLibrary type="PYTHON" name="OSUtils" path="SchedulerRobot/robot/locallibrary/cmsoUtils"/>
+ <referencedLibrary type="PYTHON" name="HTTPUtils" path="SchedulerRobot/robot/locallibrary/cmsoUtils"/>
+ <referencedLibrary type="PYTHON" name="JSONUtils" path="SchedulerRobot/robot/locallibrary/cmsoUtils"/>
+ <referencedLibrary type="PYTHON" name="FtpLibrary" path="C:/test/jerryVNFNames/SchedulerRobot/robot/library"/>
+ <pythonpath>
+ <path location="robot/library"/>
+ </pythonpath>
+ <classpath/>
+ <variableFiles path="SchedulerRobot/robot/assets/test_properties.py"/>
+ <excludedForValidation/>
+ <isValidatedFileSizeCheckingEnabled>true</isValidatedFileSizeCheckingEnabled>
+ <validatedFileMaxSize>1024</validatedFileMaxSize>
+ <isReferencedLibrariesAutoReloadEnabled>true</isReferencedLibrariesAutoReloadEnabled>
+ <isReferencedLibrariesAutoDiscoveringEnabled>true</isReferencedLibrariesAutoDiscoveringEnabled>
+ <isLibrariesAutoDiscoveringSummaryWindowEnabled>false</isLibrariesAutoDiscoveringSummaryWindowEnabled>
+</projectConfiguration>
diff --git a/cmso-robot/robot/assets/get_schedule_UUIDs.txt b/cmso-robot/robot/assets/get_schedule_UUIDs.txt
new file mode 100644
index 0000000..e49014d
--- /dev/null
+++ b/cmso-robot/robot/assets/get_schedule_UUIDs.txt
@@ -0,0 +1,7 @@
+dummy 200
+dummy 200
+dummy 200
+dummy 200
+dummy 200
+dummy 200
+not-a-scheduleID 404 \ No newline at end of file
diff --git a/cmso-robot/robot/assets/sql/InitDB.sql b/cmso-robot/robot/assets/sql/InitDB.sql
new file mode 100644
index 0000000..72667cb
--- /dev/null
+++ b/cmso-robot/robot/assets/sql/InitDB.sql
@@ -0,0 +1,3 @@
+INSERT INTO `scheduler`.`domains` (`domain`) VALUES ('ChangeManagement');
+INSERT INTO `scheduler`.`approval_types` (`domain`, `approval_type`, `approval_count`) VALUES ('ChangeManagement', 'Tier 2', '1');
+SET @@global.time_zone='+00:00'; \ No newline at end of file
diff --git a/cmso-robot/robot/assets/sql/OptimizationInProgresss.sql b/cmso-robot/robot/assets/sql/OptimizationInProgresss.sql
new file mode 100644
index 0000000..3123ad7
--- /dev/null
+++ b/cmso-robot/robot/assets/sql/OptimizationInProgresss.sql
@@ -0,0 +1,3 @@
+SET SQL_SAFE_UPDATES = 0;
+update schedules set status = 'Pending Schedule' where status = 'Optimization in Progress';
+SET SQL_SAFE_UPDATES = 1; \ No newline at end of file
diff --git a/cmso-robot/robot/assets/sql/VericaQueries.sql b/cmso-robot/robot/assets/sql/VericaQueries.sql
new file mode 100644
index 0000000..9d59f43
--- /dev/null
+++ b/cmso-robot/robot/assets/sql/VericaQueries.sql
@@ -0,0 +1,9 @@
+ SELECT distinct vnf_name, pserver_fqdn, pserver_hostname
+ from qa0_dcaecommon_views.v_vnf_vm_pserver;
+
+SELECT distinct vnf_name, pserver_fqdn, pserver_hostname from qa0_dcaecommon_views.v_vce_vm_pserver where vnf_name in ('ZRDM1MMSC04')
+UNION
+SELECT distinct vnf_name, pserver_fqdn, pserver_hostname from qa0_dcaecommon_views.v_vnf_vm_pserver where vnf_name in ('ZRDM1MMSC04')
+UNION
+SELECT distinct vnf_name, pserver_fqdn, pserver_hostname from qa0_dcaecommon_views.v_vpe_vm_pserver where vnf_name in ('ZRDM1MMSC04')
+; \ No newline at end of file
diff --git a/cmso-robot/robot/assets/sql/clearthetable.sql b/cmso-robot/robot/assets/sql/clearthetable.sql
new file mode 100644
index 0000000..e382222
--- /dev/null
+++ b/cmso-robot/robot/assets/sql/clearthetable.sql
@@ -0,0 +1,11 @@
+SET SQL_SAFE_UPDATES = 0;
+delete from DOMAIN_DATA;
+delete from CHANGE_MANAGEMENT_CHANGE_WINDOWS;
+delete from CHANGE_MANAGEMENT_RELATED_ASSETS;
+delete from CHANGE_MANAGEMENT_SCHEDULES;
+delete from CHANGE_MANAGEMENT_GROUPS;
+delete from SCHEDULE_APPROVALS;
+delete from SCHEDULE_EVENTS;
+delete from SCHEDULES;
+
+SET SQL_SAFE_UPDATES = 1;
diff --git a/cmso-robot/robot/assets/sql/demo.sql b/cmso-robot/robot/assets/sql/demo.sql
new file mode 100644
index 0000000..c099283
--- /dev/null
+++ b/cmso-robot/robot/assets/sql/demo.sql
@@ -0,0 +1,11 @@
+ SELECT DISTINCT
+ s.schedule_id, s.status, s.schedule_info, s.schedule, g.start_time,
+ d.vnf_name, d.status vnf_status, d.status_message, d.aots_change_id, d.aots_approval_status, d.mso_request_id, d.mso_status, d.aots_status, s.user_id, FROM_UNIXTIME(d.start_time/1000) as StartTime, FROM_UNIXTIME(s.create_date_time/1000) as CreateDateTime
+FROM
+ SCHEDULES s,
+ CHANGE_MANAGEMENT_GROUPS g,
+ CHANGE_MANAGEMENT_SCHEDULES d
+WHERE
+ g.schedules_id = s.id
+ AND d.change_management_groups_id = g.id
+ order by CreateDateTime desc; \ No newline at end of file
diff --git a/cmso-robot/robot/assets/sql/searchSQL.sql b/cmso-robot/robot/assets/sql/searchSQL.sql
new file mode 100644
index 0000000..952800c
--- /dev/null
+++ b/cmso-robot/robot/assets/sql/searchSQL.sql
@@ -0,0 +1,20 @@
+select distinct
+s.vnf_name as vnFName,
+s.vnf_id as vnfId,
+s.status as status,
+s.aots_change_id as aotsChangeId,
+s.start_time as startTime,
+s.finish_time as finishTime,
+g.group_id as groupId,
+g.last_instance_start_time as lastInstanceStartTime,
+g.policy_id as policyId,
+g.schedules_id as id,
+ss.schedule_id as scheduleId,
+dd.name
+from change_management_schedules s
+inner join change_management_groups g on s.change_management_groups_id = g.id
+inner join schedules ss on g.schedules_id = ss.id
+left outer join domain_data dd on ss.id = dd.schedules_id
+left outer join schedule_approvals sa on ss.id = sa.schedules_id
+inner join approval_types at on sa.approval_type_id = at.id
+left outer join change_management_related_assets cmra on cmra.change_management_schedule_id = s.id
diff --git a/cmso-robot/robot/assets/sql/selectDetails.sql b/cmso-robot/robot/assets/sql/selectDetails.sql
new file mode 100644
index 0000000..74fa390
--- /dev/null
+++ b/cmso-robot/robot/assets/sql/selectDetails.sql
@@ -0,0 +1,4 @@
+SET @@global.time_zone='+00:00';
+select distinct ss.create_date_time, s.id as id, s.vnf_name as vnf_name, s.vnf_id as vnf_id, s.status as status, s.aots_change_id as aots_change_Id, s.start_time as start_time, s.finish_time as finish_time, g.group_id as group_id, g.last_instance_start_time as last_instance_start_time, g.policy_id as policy_id, g.schedules_id as schedules_id from change_management_schedules s inner join change_management_groups g on s.change_management_groups_id = g.id inner join schedules ss on g.schedules_id = ss.id left outer join domain_data dd on ss.id = dd.schedules_id left outer join schedule_approvals sa on ss.id = sa.schedules_id inner join approval_types at on sa.approval_type_id = at.id left outer join change_management_related_assets cmra on cmra.change_management_schedule_id = s.id
+-- where ((ss.create_date_time >= TIMESTAMP('2017-07-14T21:30:02.000-0000') AND ss.create_date_time <= TIMESTAMP('2017-07-14T21:30:03.000-0000') ))
+order by id \ No newline at end of file
diff --git a/cmso-robot/robot/assets/sql/selectall.sql b/cmso-robot/robot/assets/sql/selectall.sql
new file mode 100644
index 0000000..ba41595
--- /dev/null
+++ b/cmso-robot/robot/assets/sql/selectall.sql
@@ -0,0 +1,9 @@
+select * from DOMAINS;
+select * from DOMAIN_DATA order by schedules_id desc;
+select * from CHANGE_MANAGEMENT_SCHEDULES order by id desc;
+select * from CHANGE_MANAGEMENT_CHANGE_WINDOWS;
+select * from CHANGE_MANAGEMENT_GROUPS;
+select * from SCHEDULES order by id desc;
+select * from APPROVAL_TYPES;
+select * from SCHEDULE_APPROVALS;
+select * from SCHEDULE_EVENTS; \ No newline at end of file
diff --git a/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyDomain.json.template b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyDomain.json.template
new file mode 100644
index 0000000..d806855
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyDomain.json.template
@@ -0,0 +1,30 @@
+{
+ "domain" : "",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+ "concurrencyLimit" : 10,
+ "policyId" : "dummy-id",
+ "vnfDetails" : [{
+ "groupId" : "",
+ "node" : [
+ "dummy{node}"
+ ],
+ "changeWindow" : [{
+ "startTime" : "${start_time1}",
+ "endTime" : "${end_time1}"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyScheduleID.json.template b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyScheduleID.json.template
new file mode 100644
index 0000000..a8315f6
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyScheduleID.json.template
@@ -0,0 +1,30 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+ "concurrencyLimit" : 10,
+ "policyId" : "dummy-id",
+ "vnfDetails" : [{
+ "groupId" : "",
+ "node" : [
+ "dummy{node}"
+ ],
+ "changeWindow" : [{
+ "startTime" : "${start_time1}",
+ "endTime" : "${end_time1}"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyScheduleName.json.template b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyScheduleName.json.template
new file mode 100644
index 0000000..29a0a6a
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyScheduleName.json.template
@@ -0,0 +1,30 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+ "concurrencyLimit" : 10,
+ "policyId" : "dummy-id",
+ "vnfDetails" : [{
+ "groupId" : "",
+ "node" : [
+ "dummy{node}"
+ ],
+ "changeWindow" : [{
+ "startTime" : "${start_time1}",
+ "endTime" : "${end_time1}"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyUserID.json.template b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyUserID.json.template
new file mode 100644
index 0000000..e239d7d
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyUserID.json.template
@@ -0,0 +1,30 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+ "concurrencyLimit" : 10,
+ "policyId" : "dummy-id",
+ "vnfDetails" : [{
+ "groupId" : "",
+ "node" : [
+ "dummy{node}"
+ ],
+ "changeWindow" : [{
+ "startTime" : "${start_time1}",
+ "endTime" : "${end_time1}"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowIncorrectPolicyId.json.template b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowIncorrectPolicyId.json.template
new file mode 100644
index 0000000..c5bab19
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowIncorrectPolicyId.json.template
@@ -0,0 +1,30 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+ "concurrencyLimit" : 10,
+ "policyId" : "string",
+ "vnfDetails" : [{
+ "groupId" : "",
+ "node" : [
+ "dummy{node}"
+ ],
+ "changeWindow" : [{
+ "startTime" : "${start_time1}",
+ "endTime" : "${end_time1}"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowIncorrectWorkflow.json.template b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowIncorrectWorkflow.json.template
new file mode 100644
index 0000000..b7eedc5
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowIncorrectWorkflow.json.template
@@ -0,0 +1,30 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Not A Workflow"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+ "concurrencyLimit" : 10,
+ "policyId" : "dummy-id",
+ "vnfDetails" : [{
+ "groupId" : "",
+ "node" : [
+ "dummy{node}"
+ ],
+ "changeWindow" : [{
+ "startTime" : "${start_time1}",
+ "endTime" : "${end_time1}"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNegativeNormalDurationInSeconds.json.template b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNegativeNormalDurationInSeconds.json.template
new file mode 100644
index 0000000..8cd0703
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNegativeNormalDurationInSeconds.json.template
@@ -0,0 +1,30 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : -5,
+ "additionalDurationInSeconds" : 10,
+ "concurrencyLimit" : 10,
+ "policyId" : "dummy-id",
+ "vnfDetails" : [{
+ "groupId" : "",
+ "node" : [
+ "dummy{node}"
+ ],
+ "changeWindow" : [{
+ "startTime" : "${start_time1}",
+ "endTime" : "${end_time1}"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNoEndTime.json.template b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNoEndTime.json.template
new file mode 100644
index 0000000..2973c89
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNoEndTime.json.template
@@ -0,0 +1,30 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+ "concurrencyLimit" : 10,
+ "policyId" : "dummy-id",
+ "vnfDetails" : [{
+ "groupId" : "",
+ "node" : [
+ "dummy{node}"
+ ],
+ "changeWindow" : [{
+ "startTime" : "${start_time1}",
+ "endTime" : ""
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNoNodeName.json.template b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNoNodeName.json.template
new file mode 100644
index 0000000..9c5670c
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNoNodeName.json.template
@@ -0,0 +1,30 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+ "concurrencyLimit" : 10,
+ "policyId" : "dummy-id",
+ "vnfDetails" : [{
+ "groupId" : "",
+ "node" : [
+ ""
+ ],
+ "changeWindow" : [{
+ "startTime" : "${start_time1}",
+ "endTime" : "${end_time1}"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNoStartTime.json.template b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNoStartTime.json.template
new file mode 100644
index 0000000..e97c46e
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNoStartTime.json.template
@@ -0,0 +1,30 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+ "concurrencyLimit" : 10,
+ "policyId" : "dummy-id",
+ "vnfDetails" : [{
+ "groupId" : "",
+ "node" : [
+ "dummy{node}"
+ ],
+ "changeWindow" : [{
+ "startTime" : "",
+ "endTime" : "${end_time1}"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowSwitchedTime.json.template b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowSwitchedTime.json.template
new file mode 100644
index 0000000..1c2c3ce
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowSwitchedTime.json.template
@@ -0,0 +1,30 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+ "concurrencyLimit" : 10,
+ "policyId" : "dummy-id",
+ "vnfDetails" : [{
+ "groupId" : "",
+ "node" : [
+ "dummy{node}"
+ ],
+ "changeWindow" : [{
+ "startTime" : "${end_time1}",
+ "endTime" : "${start_time1}"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyAdditionalDuration.json.template b/cmso-robot/robot/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyAdditionalDuration.json.template
new file mode 100644
index 0000000..5c9e0a3
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyAdditionalDuration.json.template
@@ -0,0 +1,23 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ "vnfDetails" : [{
+ "groupId" : "",
+ "node" : [
+ "VNFName1${testid}",
+ "VNFName2${testid}",
+ "VNFName3${testid}"
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyDomain.json.template b/cmso-robot/robot/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyDomain.json.template
new file mode 100644
index 0000000..19c1d87
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyDomain.json.template
@@ -0,0 +1,23 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ "vnfDetails" : [{
+ "groupId" : "",
+ "node" : [
+ "VNFName1${testid}",
+ "VNFName2${testid}",
+ "VNFName3${testid}"
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyScheduleId.json.template b/cmso-robot/robot/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyScheduleId.json.template
new file mode 100644
index 0000000..ab92d18
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyScheduleId.json.template
@@ -0,0 +1,23 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ "vnfDetails" : [{
+ "groupId" : "",
+ "node" : [
+ "VNFName1${testid}",
+ "VNFName2${testid}",
+ "VNFName3${testid}"
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyUserId.json.template b/cmso-robot/robot/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyUserId.json.template
new file mode 100644
index 0000000..9de749c
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyUserId.json.template
@@ -0,0 +1,23 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ "vnfDetails" : [{
+ "groupId" : "",
+ "node" : [
+ "VNFName1${testid}",
+ "VNFName2${testid}",
+ "VNFName3${testid}"
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyDomain.json.template b/cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyDomain.json.template
new file mode 100644
index 0000000..86ae4b8
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyDomain.json.template
@@ -0,0 +1,20 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ "vnfDetails" : [{
+ "node" : [
+ "dummy{node}"
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyScheduleId.json.template b/cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyScheduleId.json.template
new file mode 100644
index 0000000..ba555ac
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyScheduleId.json.template
@@ -0,0 +1,20 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ "vnfDetails" : [{
+ "node" : [
+ "dummy{node}"
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyScheduleName.json.template b/cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyScheduleName.json.template
new file mode 100644
index 0000000..b5cf73e
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyScheduleName.json.template
@@ -0,0 +1,23 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+
+ "vnfDetails" : [{
+ "node" : [
+ "dummy{node}"
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptySchedulingInfo.json.template b/cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptySchedulingInfo.json.template
new file mode 100644
index 0000000..461f166
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptySchedulingInfo.json.template
@@ -0,0 +1,14 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyUserId.json.template b/cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyUserId.json.template
new file mode 100644
index 0000000..a2a4ba4
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyUserId.json.template
@@ -0,0 +1,14 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/changemanagement/MultipleVnfImmediate.json.template b/cmso-robot/robot/assets/templates/changemanagement/MultipleVnfImmediate.json.template
new file mode 100644
index 0000000..542e19e
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/changemanagement/MultipleVnfImmediate.json.template
@@ -0,0 +1,24 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "${workflow}"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+ "vnfDetails" : [{
+ "groupId" : "group",
+ "node" : [
+ "${node1}",
+ "${node2}",
+ "${node3}"
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/changemanagement/OneGroupMultipleVNFsOneChangeWindow.json.template b/cmso-robot/robot/assets/templates/changemanagement/OneGroupMultipleVNFsOneChangeWindow.json.template
new file mode 100644
index 0000000..4630faa
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/changemanagement/OneGroupMultipleVNFsOneChangeWindow.json.template
@@ -0,0 +1,32 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "${workflow}"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+ "concurrencyLimit" : 10,
+ "policyId" : "dummy-policy-id",
+ "vnfDetails" : [{
+ "groupId" : "group",
+ "node" : [
+ "${node1}",
+ "${node2}",
+ "${node3}"
+ ],
+ "changeWindow" : [{
+ "startTime" : "${start_time1}",
+ "endTime" : "${end_time1}"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/changemanagement/OneGroupMultipleVNSsTwoChangeWindows.json.template b/cmso-robot/robot/assets/templates/changemanagement/OneGroupMultipleVNSsTwoChangeWindows.json.template
new file mode 100644
index 0000000..061b4f6
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/changemanagement/OneGroupMultipleVNSsTwoChangeWindows.json.template
@@ -0,0 +1,37 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "${workflow}"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+ "concurrencyLimit" : 10,
+ "policyId" : "dummy-policy-id",
+ "vnfDetails" : [{
+ "groupId" : "Group1",
+ "node" : [
+ "${node1}",
+ "${node2}",
+ "${node3}",
+ "${node4}"
+ ],
+ "changeWindow" : [{
+ "startTime" : "${start_time1}",
+ "endTime" : "${end_time1}"
+ },{
+ "startTime" : "${start_time2}",
+ "endTime" : "${end_time2}"
+ }
+ ]
+ }
+ ]
+ }
+}
+
diff --git a/cmso-robot/robot/assets/templates/changemanagement/OneVnfImmediate.json.template b/cmso-robot/robot/assets/templates/changemanagement/OneVnfImmediate.json.template
new file mode 100644
index 0000000..c108c15
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/changemanagement/OneVnfImmediate.json.template
@@ -0,0 +1,25 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "${workflow}",
+ "plans" : "Run ${workflow}",
+ "question.000000000000001" : "Yes"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+ "vnfDetails" : [{
+ "groupId" : "group1",
+ "node" : [
+ "${node1}"
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/changemanagement/OneVnfImmediateIncorrectWorkflow.json.template b/cmso-robot/robot/assets/templates/changemanagement/OneVnfImmediateIncorrectWorkflow.json.template
new file mode 100644
index 0000000..e91c653
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/changemanagement/OneVnfImmediateIncorrectWorkflow.json.template
@@ -0,0 +1,21 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Not A Workflow"
+ }
+ ],
+ "schedulingInfo" : {
+ "vnfDetails" : [{
+ "groupId" : "group",
+ "node" : [
+ "${node1}"
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/changemanagement/OneVnfImmediateReplaceVNFInfra.json.template b/cmso-robot/robot/assets/templates/changemanagement/OneVnfImmediateReplaceVNFInfra.json.template
new file mode 100644
index 0000000..d896a62
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/changemanagement/OneVnfImmediateReplaceVNFInfra.json.template
@@ -0,0 +1,23 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "ReplaceVnfInfra"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+ "vnfDetails" : [{
+ "groupId" : "group",
+ "node" : [
+ "${node1}"
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/changemanagement/OneVnfOneChangeWindow.json.template b/cmso-robot/robot/assets/templates/changemanagement/OneVnfOneChangeWindow.json.template
new file mode 100644
index 0000000..a3ada80
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/changemanagement/OneVnfOneChangeWindow.json.template
@@ -0,0 +1,30 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "${workflow}"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+ "concurrencyLimit" : 10,
+ "policyId" : "dummy-policy-id",
+ "vnfDetails" : [{
+ "groupId" : "group",
+ "node" : [
+ "${node1}"
+ ],
+ "changeWindow" : [{
+ "startTime" : "${start_time1}",
+ "endTime" : "${end_time1}"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/changemanagement/OneVnfOneChangeWindowEmptyCallbackData.json.template b/cmso-robot/robot/assets/templates/changemanagement/OneVnfOneChangeWindowEmptyCallbackData.json.template
new file mode 100644
index 0000000..f1fe686
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/changemanagement/OneVnfOneChangeWindowEmptyCallbackData.json.template
@@ -0,0 +1,25 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "",
+ "WorkflowName" : "Build Software Upgrade for vNFs"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+ "concurrencyLimit" : 10,
+ "policyId" : "dummy-policy-id",
+ "vnfDetails" : [{
+ "groupId" : "group",
+ "node" : [
+ "${node1}"
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/changemanagement/OneVnfOneChangeWindowEmptyCallbackURL.json.template b/cmso-robot/robot/assets/templates/changemanagement/OneVnfOneChangeWindowEmptyCallbackURL.json.template
new file mode 100644
index 0000000..e5c691e
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/changemanagement/OneVnfOneChangeWindowEmptyCallbackURL.json.template
@@ -0,0 +1,30 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Build Software Upgrade for vNFs"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+ "concurrencyLimit" : 10,
+ "policyId" : "dummy-policy-id",
+ "vnfDetails" : [{
+ "groupId" : "group",
+ "node" : [
+ "${node1}"
+ ],
+ "changeWindow" : [{
+ "startTime" : "${start_time1}",
+ "endTime" : "${end_time1}"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/changemanagement/OneVnfOneChangeWindowReplaceVNFInfra.json.template b/cmso-robot/robot/assets/templates/changemanagement/OneVnfOneChangeWindowReplaceVNFInfra.json.template
new file mode 100644
index 0000000..11a50cb
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/changemanagement/OneVnfOneChangeWindowReplaceVNFInfra.json.template
@@ -0,0 +1,30 @@
+{
+ "domain" : "ChangeManagement",
+ "scheduleId" : "${uuid}",
+ "scheduleName" : "${uuid}",
+ "userId" : "${userId}",
+ "domainData" : [{
+ "CallbackUrl" : "${callbackUrl}",
+ "CallbackData" : "${callbackData}",
+ "WorkflowName" : "Replace"
+ }
+ ],
+ "schedulingInfo" : {
+ "normalDurationInSeconds" : 100,
+ "additionalDurationInSeconds" : 10,
+ "concurrencyLimit" : 10,
+ "policyId" : "dummy-policy-id",
+ "vnfDetails" : [{
+ "groupId" : "group",
+ "node" : [
+ "${node1}"
+ ],
+ "changeWindow" : [{
+ "startTime" : "${start_time1}",
+ "endTime" : "${end_time1}"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/cmso-robot/robot/assets/templates/changemanagement/VidCallbackData.json.template b/cmso-robot/robot/assets/templates/changemanagement/VidCallbackData.json.template
new file mode 100644
index 0000000..ed3be93
--- /dev/null
+++ b/cmso-robot/robot/assets/templates/changemanagement/VidCallbackData.json.template
@@ -0,0 +1,40 @@
+{
+ "requestType" : "Update",
+ "requestDetails" : [{
+ "vnfName" : "dummy-vnf",
+ "vnfInstanceId" : "dummy-vnfinstance-id",
+ "modelInfo" : {
+ "modelType" : "vnf",
+ "modelInvariantId" : "dummy-id",
+ "modelVersionId" : "dummy-id",
+ "modelName" : "dummy",
+ "modelCustomizationId" : "dummy-id"
+ },
+ "cloudConfiguration" : {
+ "lcpCloudRegionId" : "dummy",
+ "tenantId" : "dummy-id"
+ },
+ "requestInfo" : {
+ "source" : "VID",
+ "suppressRollback" : false,
+ "requestorId" : "az2016"
+ },
+ "relatedInstanceList" : [{
+ "relatedInstance" : {
+ "instanceId" : "dummy-id",
+ "modelInfo" : {
+ "modelType" : "service",
+ "modelInvariantId" : "dummy-id",
+ "modelVersionId" : "dummy-id",
+ "modelName" : "dummy-id",
+ "modelVersion" : "4.0"
+ }
+ }
+ }
+ ],
+ "requestParameters" : {
+ "usePreload" : true
+ }
+ }
+ ]
+}
diff --git a/cmso-robot/robot/assets/test_properties.py b/cmso-robot/robot/assets/test_properties.py
new file mode 100644
index 0000000..cab823d
--- /dev/null
+++ b/cmso-robot/robot/assets/test_properties.py
@@ -0,0 +1,41 @@
+from os import listdir
+from os.path import isfile, join
+
+# Should be provided in Jenkins job
+
+GLOBAL_SCHEDULER_HOST = "dummy-host"
+GLOBAL_SCHEDULER_PORT = dummy-port
+GLOBAL_SCHEDULER_PROTOCOL = "https"
+GLOBAL_VID_USERID = "onap-user"
+GLOBAL_SCHEDULER_PASSWORD = "pwd"
+
+GLOBAL_SCHEDULER_USER = "dummy-user"
+GLOBAL_APPLICATION_ID= "schedulertest"
+GLOBAL_VTM_URL="http://localhost:25055"
+GLOBAL_LISTCHANGE_PATH="/service=searchchangerecord.vtm.att.com/vtm/searchChangeRecord/v1/listChangeRecords/version=1.0.0/envContext=TEST/routeOffer=DEFAULT"
+
+
+GLOBAL_VTM_PROTO="http"
+GLOBAL_VTM_HOST="dummy-host"
+GLOBAL_VTM_CLOSE_PORT=31127
+
+GLOBAL_VTM_USER="dummy-user"
+GLOBAL_VTM_PASSWORD="dummy-pwd"
+GLOBAL_VID_CALLBACK_URL="http://localhost:8900/scheduler/v1/loopbacktest/vid"
+cmFailurePath= "robot/assets/templates/FailureCasesChangeManagement"
+GLOBAL_CM_FAILURE_TEMPLATES= [f for f in listdir(cmFailurePath) if isfile(join(cmFailurePath, f))]
+
+OneVNFImmediateFailurePath="robot/assets/templates/OneVNFImmediateFailureCases"
+GLOBAL_CM_ONEVNF_FAILURE_TEMPLATES=[f for f in listdir(OneVNFImmediateFailurePath) if isfile(join(OneVNFImmediateFailurePath, f))]
+
+MultipleVNFImmediateFailurePath="robot/assets/templates/MutipleVNFImmediateFailureCases"
+GLOBAL_CM_MULTIPLE_VNF_FAILURE_TEMPLATES=[f for f in listdir(MultipleVNFImmediateFailurePath) if isfile(join(MultipleVNFImmediateFailurePath, f))]
+
+
+DELETE_TICKET_ENVS = [
+ {"scheduler" : "dummy", "vtm" : "dummy"},
+ {"scheduler" : "dummy", "vtm" : "dummy"},
+]
+
+NODES = "dummy,dummy,dummy,dummy";
+ \ No newline at end of file
diff --git a/cmso-robot/robot/locallibrary/cmsoUtils/CurlLibrary.py b/cmso-robot/robot/locallibrary/cmsoUtils/CurlLibrary.py
new file mode 100644
index 0000000..44c6229
--- /dev/null
+++ b/cmso-robot/robot/locallibrary/cmsoUtils/CurlLibrary.py
@@ -0,0 +1,13 @@
+from curl import Curl
+
+class CurlLibrary:
+
+
+ def get_zip(self, url, filename):
+ fp = open(filename, "wb")
+ c = Curl()
+ c.get(url, )
+ c.set_option(c.WRITEDATA, fp)
+ c.perform()
+ c.close()
+ fp.close() \ No newline at end of file
diff --git a/cmso-robot/robot/locallibrary/cmsoUtils/HTTPUtils.py b/cmso-robot/robot/locallibrary/cmsoUtils/HTTPUtils.py
new file mode 100644
index 0000000..f9d380c
--- /dev/null
+++ b/cmso-robot/robot/locallibrary/cmsoUtils/HTTPUtils.py
@@ -0,0 +1,21 @@
+import urllib
+from selenium import webdriver
+import base64
+
+class HTTPUtils:
+ """HTTPUtils is common resource for simple http helper keywords."""
+
+ def url_encode_string(self, barestring):
+ """URL Encode String takes in a string and converts into 'percent-encoded' string"""
+ return urllib.quote_plus(barestring)
+
+ def ff_profile(self):
+ fp =webdriver.FirefoxProfile()
+ fp.set_preference("dom.max_script_run_time",120)
+ fp.update_preferences()
+ return fp.path
+
+ def b64_encode(self, instring):
+ ""
+ return base64.b64encode(instring)
+
diff --git a/cmso-robot/robot/locallibrary/cmsoUtils/JSONUtils.py b/cmso-robot/robot/locallibrary/cmsoUtils/JSONUtils.py
new file mode 100644
index 0000000..5df1e5c
--- /dev/null
+++ b/cmso-robot/robot/locallibrary/cmsoUtils/JSONUtils.py
@@ -0,0 +1,37 @@
+import json
+
+from deepdiff import DeepDiff
+
+class JSONUtils:
+ """JSONUtils is common resource for simple json helper keywords."""
+
+ def json_equals(self, left, right):
+ """JSON Equals takes in two strings or json objects, converts them into json if needed and then compares them, returning if they are equal or not."""
+ if isinstance(left, basestring):
+ left_json = json.loads(left);
+ else:
+ left_json = left;
+ if isinstance(right, basestring):
+ right_json = json.loads(right);
+ else:
+ right_json = right;
+
+ ddiff = DeepDiff(left_json, right_json, ignore_order=True);
+ if ddiff == {}:
+ return True;
+ else:
+ return False;
+
+ def json_escape(self, jsonObject):
+ jsonstr = json.dumps(jsonObject)
+ outstr = jsonstr.replace('"', '\\"').replace('\n', '\\n')
+ return outstr
+
+ def make_list_into_dict(self, listOfDicts, key):
+ """ Converts a list of dicts that contains a field that has a unique key into a dict of dicts """
+ d = {}
+ if isinstance(listOfDicts, list):
+ for thisDict in listOfDicts:
+ v = thisDict[key]
+ d[v] = thisDict
+ return d \ No newline at end of file
diff --git a/cmso-robot/robot/locallibrary/cmsoUtils/OSUtils.py b/cmso-robot/robot/locallibrary/cmsoUtils/OSUtils.py
new file mode 100644
index 0000000..78968f0
--- /dev/null
+++ b/cmso-robot/robot/locallibrary/cmsoUtils/OSUtils.py
@@ -0,0 +1,14 @@
+from sys import platform
+
+class OSUtils:
+ """ Utilities useful for constructing OpenStack HEAT requests """
+
+ def get_normalized_os(self):
+ os = platform
+ if platform == "linux" or platform == "linux2":
+ os = 'linux64'
+ elif platform == "darwin":
+ os = 'mac64'
+ elif platform == "win32":
+ os = platform
+ return os
diff --git a/cmso-robot/robot/locallibrary/cmsoUtils/RequestsClientCert.py b/cmso-robot/robot/locallibrary/cmsoUtils/RequestsClientCert.py
new file mode 100644
index 0000000..e1fd66f
--- /dev/null
+++ b/cmso-robot/robot/locallibrary/cmsoUtils/RequestsClientCert.py
@@ -0,0 +1,7 @@
+
+class RequestsClientCert:
+ """RequestsClientCert allows adding a client cert to the Requests Robot Library."""
+
+ def add_client_cert(self, session, cert):
+ """Add Client Cert takes in a requests session object and a string path to the cert"""
+ session.cert = cert \ No newline at end of file
diff --git a/cmso-robot/robot/locallibrary/cmsoUtils/StringTemplater.py b/cmso-robot/robot/locallibrary/cmsoUtils/StringTemplater.py
new file mode 100644
index 0000000..680600f
--- /dev/null
+++ b/cmso-robot/robot/locallibrary/cmsoUtils/StringTemplater.py
@@ -0,0 +1,8 @@
+from string import Template
+
+class StringTemplater:
+ """StringTemplater is common resource for templating with strings."""
+
+ def template_string(self, template, values):
+ """Template String takes in a string and its values and converts it using the string.Template class"""
+ return Template(template).substitute(values) \ No newline at end of file
diff --git a/cmso-robot/robot/locallibrary/cmsoUtils/UUID.py b/cmso-robot/robot/locallibrary/cmsoUtils/UUID.py
new file mode 100644
index 0000000..15567ce
--- /dev/null
+++ b/cmso-robot/robot/locallibrary/cmsoUtils/UUID.py
@@ -0,0 +1,8 @@
+import uuid
+
+class UUID:
+ """UUID is a simple library that generates a uuid"""
+
+ def generate_UUID(self):
+ """generate a uuid"""
+ return uuid.uuid4() \ No newline at end of file
diff --git a/cmso-robot/robot/resources/browser_setup.robot b/cmso-robot/robot/resources/browser_setup.robot
new file mode 100644
index 0000000..032759e
--- /dev/null
+++ b/cmso-robot/robot/resources/browser_setup.robot
@@ -0,0 +1,50 @@
+*** Settings ***
+Documentation The main interface for interacting with VID. It handles low level stuff like managing the selenium request library and VID required steps
+Library Collections
+Library OSUtils
+Library OperatingSystem
+Library Selenium2Library
+
+*** Variables ***
+${CHROME_DRIVER_WIN32_PATH} drivers/win32
+${CHROME_DRIVER_MAC64_PATH} drivers/mac64
+${CHROME_DRIVER_LINUX64_PATH} drivers/linux64
+${CHROME_DRIVER_WIN32} ${CHROME_DRIVER_WIN32_PATH}/chromedriver.exe
+${CHROME_DRIVER_MAC64} ${CHROME_DRIVER_MAC64_PATH} /chromedriver
+${CHROME_DRIVER_LINUX64} ${CHROME_DRIVER_LINUX64_PATH}/chromedriver
+
+*** Keywords ***
+Setup Browser
+ [Documentation] Sets up browser based upon the value of
+ [Arguments] ${browser}
+ Run Keyword If '${browser}' == 'firefox' Setup Browser Firefox
+ Run Keyword If '${browser}' == 'chrome' Setup Browser Chrome
+ Log Running with ${browser}
+
+Setup Browser Firefox
+ ${dc} Evaluate sys.modules['selenium.webdriver'].DesiredCapabilities.FIREFOX sys, selenium.webdriver
+ Set To Dictionary ${dc} elementScrollBehavior 1
+ Create Webdriver Firefox desired_capabilities=${dc}
+ ##Set Global Variable ${GLOBAL_SELENIUM_BROWSER_CAPABILITIES} ${dc}
+
+
+ Setup Browser Chrome
+ ${os}= Get Normalized Os
+ Log Normalized OS=${os}
+ Run Keyword If '${os}' == 'win32' Append To Environment Variable PATH ${CHROME_DRIVER_WIN32_PATH}
+ ##Run Keyword If '${os}' == 'win32' Set Environment Variable webdriver.chrome.driver ${CHROME_DRIVER_WIN32}
+ Run Keyword If '${os}' == 'mac64' Append To Environment Variable PATH ${CHROME_DRIVER_MAC64_PATH}
+ #Run Keyword If '${os}' == 'mac64' Set Environment Variable webdriver.chrome.driver ${CHROME_DRIVER_MAC64}
+ Run Keyword If '${os}' == 'linux64' Append To Environment Variable PATH ${CHROME_DRIVER_LINUX64_PATH}
+ #Run Keyword if '${os}' == 'linux64' Set Environment Variable webdriver.chrome.driver ${CHROME_DRIVER_LINUX64}
+ ${chrome options}= Evaluate sys.modules['selenium.webdriver'].ChromeOptions() sys
+ Call Method ${chrome options} add_argument no-sandbox
+ ${dc} Evaluate sys.modules['selenium.webdriver'].DesiredCapabilities.CHROME sys, selenium.webdriver
+ Set To Dictionary ${dc} elementScrollBehavior 1
+ Create Webdriver Chrome chrome_options=${chrome_options} desired_capabilities=${dc}
+ #Set Global Variable ${GLOBAL_SELENIUM_BROWSER_CAPABILITIES} ${dc}
+
+Handle ATT Speed Bump
+ [Documentation] Handle AT&T Speed Bump when accessing Rackspace UI from AT&T network
+ ${test} ${value}= Run keyword and ignore error Title Should Be Notice - Uncategorized Site
+ Run keyword If '${test}' == 'PASS' Click Element xpath=//a[contains(@href, 'accepted-Notify-Uncategorized')] \ No newline at end of file
diff --git a/cmso-robot/robot/resources/files.robot b/cmso-robot/robot/resources/files.robot
new file mode 100644
index 0000000..fcfffbb
--- /dev/null
+++ b/cmso-robot/robot/resources/files.robot
@@ -0,0 +1,50 @@
+*** Settings ***
+Documentation Some handy Keywords for accessing log files over SSH. Assumptions are that logs will belong to users other than the currently logged in user and that sudo will be required
+Library OperatingSystem
+Library SSHLibrary
+Library HttpLibrary.HTTP
+Library String
+Library Collections
+
+*** Variables ***
+
+*** Keywords ***
+Open Connection And Log In
+ [Documentation] Open a connection using the passed user and SSH key. Connection alias will be the host name by default.
+ [Arguments] ${HOST} ${user} ${pvt} ${password}= ${alias}=${HOST} ${timeout}=120s
+ Open Connection ${HOST} alias=${alias} timeout=${timeout}
+ Login With Public Key ${user} ${pvt} password=${password} delay=0.5 seconds
+
+Grep Local File
+ [Documentation] Grep the passed file name and return all of the lines that match the passed pattern using the current connection
+ [Arguments] ${pattern} ${fullpath}
+ ${output}= Execute Command grep ${pattern} ${fullpath}
+ [Return] ${output}
+
+ Grep File on Host
+ [Documentation] Grep the passed file name and return all of the lines that match the passed pattern using passed connection alias/host
+ [Arguments] ${host} ${pattern} ${fullpath}
+ Switch Connection ${host}
+ ${output}= Grep Local File ${pattern} ${fullpath}
+ @{lines}= Split To Lines ${output}
+ [Return] @{lines}
+
+Grep File on Hosts
+ [Documentation] Grep the passed file name and return all of the lines that match the passed pattern using passed list of connections
+ [Arguments] ${HOSTS} ${pattern} ${fullpath}
+ &{map}= Create Dictionary
+ :FOR ${HOST} IN @{HOSTS}
+ \ Log ${HOST}
+ \ @{lines}= Grep File on Host ${HOST} ${pattern} ${fullpath}
+ \ &{map}= Create Dictionary ${HOST}=@{lines} &{map}
+ [Return] &{map}
+
+Tail File on Host Until
+ [Documentation] Tail log file into grep which returns file lines containing the grep pattern. Will timeout after timeout= if expected pattern not received.
+ [Arguments] ${host} ${pattern} ${fullpath} ${expected} ${timeout}=60 ${options}=-c -0
+ Switch Connection ${host}
+ ${tailcommand}= Catenate tail ${options} -f ${fullpath} | grep --color=never ${pattern}
+ Write ${tailcommand}
+ ${stdout}= Read Until Regexp ${expected}
+ @{lines}= Split To Lines ${stdout}
+ [Return] @{lines}
diff --git a/cmso-robot/robot/resources/json_templater.robot b/cmso-robot/robot/resources/json_templater.robot
new file mode 100644
index 0000000..b057251
--- /dev/null
+++ b/cmso-robot/robot/resources/json_templater.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Documentation This resource is filling out json string templates and returning the json back
+Library RequestsLibrary
+Library StringTemplater
+Library OperatingSystem
+
+*** Keywords ***
+Fill JSON Template
+ [Documentation] Runs substitution on template to return a filled in json
+ [Arguments] ${json} ${arguments}
+ ${returned_string}= Template String ${json} ${arguments}
+ ${returned_json}= To Json ${returned_string}
+ [Return] ${returned_json}
+
+Fill JSON Template File
+ [Documentation] Runs substitution on template to return a filled in json
+ [Arguments] ${json_file} ${arguments}
+ ${json}= OperatingSystem.Get File ${json_file}
+ ${returned_json}= Fill JSON Template ${json} ${arguments}
+ [Return] ${returned_json} \ No newline at end of file
diff --git a/cmso-robot/robot/resources/misc.robot b/cmso-robot/robot/resources/misc.robot
new file mode 100644
index 0000000..8409601
--- /dev/null
+++ b/cmso-robot/robot/resources/misc.robot
@@ -0,0 +1,42 @@
+*** Settings ***
+Library Collections
+Library String
+Library UUID
+Library Process
+Library HttpLibrary.HTTP
+Documentation Miscellaneous keywords
+
+Resource json_templater.robot
+Resource scheduler_requests/create_schedule.robot
+
+
+*** Variables ***
+
+*** Keywords ***
+
+Validate Status
+ [Documentation] Fail unless the Request response is in the passed list of valid HTTP status codes.
+ [Arguments] ${resp} ${valid_status_list}
+ ${status_code} Convert To String ${resp.status_code}
+ Return From Keyword If '${resp.status_code}' in ${valid_status_list}
+ Fail ${resp.status_code}
+
+Validate JSON Error
+ [Documentation] Fails if messageIds do not match. expected_errors should be a list but a string would likely work as well
+ [Arguments] ${resp_json} ${expected_errors}
+ ${result}= Get From Dictionary ${resp_json['requestError']} messageId
+ Should Contain ${expected_errors} ${result} #checks expected_errors list for the actual error received from schedule
+
+Check ATTIDs Template
+ [Documentation] This just checks a list of uuids
+ [Arguments] ${expected_status_code} ${template_folder}
+ ${request_file}= Convert to String OneVnfImmediateATTID.json.template
+ ${attid_file}= OperatingSystem.Get File robot/assets/AOTS_CM_IDs.txt
+ @{attids}= Split to lines ${attid_file}
+ :for ${attid} in @{attids}
+ \ ${uuid}= Generate UUID
+ \ ${resp}= Run Keyword and Continue on Failure Create Schedule ${uuid} ${request_file} ${template_folder} attid=${attid}
+ \ Run Keyword and Continue on Failure Should Be Equal as Strings ${resp.status_code} ${expected_status_code}
+ \ ${reps}= Delete Change Management auth schedules/${uuid}
+
+ \ No newline at end of file
diff --git a/cmso-robot/robot/resources/scheduler_common.robot b/cmso-robot/robot/resources/scheduler_common.robot
new file mode 100644
index 0000000..7fa8a59
--- /dev/null
+++ b/cmso-robot/robot/resources/scheduler_common.robot
@@ -0,0 +1,85 @@
+*** Settings ***
+Documentation The private interface for interacting with Openstack. It handles low level stuff like managing the authtoken and Openstack required fields
+
+Library Collections
+Library RequestsLibrary
+Library UUID
+Library HTTPUtils
+Library String
+Resource misc.robot
+*** Variables ***
+*** Variables ***
+${SCHEDULER_PATH} /scheduler/v1
+${CHANGE_MANAGEMENT_PATH} ${SCHEDULER_PATH}/ChangeManagement
+${valid_status_codes} 200 202 400 404 204 409
+#**************** Test Case Variables ******************
+
+*** Keywords ***
+
+
+Post Change Management
+ [Documentation] Runs a scheduler POST request
+ [Arguments] ${alias} ${resource} ${data}={}
+ ${data_path}= Catenate ${CHANGE_MANAGEMENT_PATH}/${resource}
+ ${resp}= Post Scheduler ${alias} ${data_path} ${data}
+ [Return] ${resp}
+
+Delete Change Management
+ [Documentation] Runs a scheduler DELETE request (this may need to be changed for 1802 US change Delete schedule to Cancel Schedule)
+ [Arguments] ${alias} ${resource}
+ ${data_path}= Catenate ${CHANGE_MANAGEMENT_PATH}/${resource}
+ ${resp}= Delete Scheduler ${alias} ${data_path}
+ [Return] ${resp}
+
+Get Change Management
+ [Documentation] Runs a scheduler GET request
+ [Arguments] ${alias} ${resource}
+ ${data_path}= Catenate ${CHANGE_MANAGEMENT_PATH}/${resource}
+ ${resp}= Get Scheduler ${alias} ${data_path}
+ [Return] ${resp}
+
+Post Scheduler
+ [Documentation] Runs a scheduler POST request
+ [Arguments] ${alias} ${data_path} ${data}={}
+ ${url}= Catenate ${GLOBAL_SCHEDULER_PROTOCOL}://${GLOBAL_SCHEDULER_HOST}:${GLOBAL_SCHEDULER_PORT}
+ ${uuid}= Generate UUID
+ ${proxies}= Create Dictionary no=pass
+ ${session}= Create Session ${alias} ${url}
+ ${auth_string}= B64 Encode ${GLOBAL_SCHEDULER_USER}:${GLOBAL_SCHEDULER_PASSWORD}
+ ${headers}= Create Dictionary Accept=application/json Content-Type=application/json X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid} X-FromAppId=${GLOBAL_APPLICATION_ID} Authorization=Basic ${auth_string}
+ ${resp}= Post Request ${alias} ${data_path} headers=${headers} data=${data}
+ Log Received response from scheduler ${resp.text}
+ ${valid}= Split String ${valid_status_codes}
+
+ Validate Status ${resp} ${valid}
+ [Return] ${resp}
+
+Delete Scheduler
+ [Documentation] Runs a scheduler POST request
+ [Arguments] ${alias} ${data_path}
+ ${url}= Catenate ${GLOBAL_SCHEDULER_PROTOCOL}://${GLOBAL_SCHEDULER_HOST}:${GLOBAL_SCHEDULER_PORT}
+ ${uuid}= Generate UUID
+ ${proxies}= Create Dictionary no=pass
+ ${session}= Create Session ${alias} ${url}
+ ${auth_string}= B64 Encode ${GLOBAL_SCHEDULER_USER}:${GLOBAL_SCHEDULER_PASSWORD}
+ ${headers}= Create Dictionary Accept=application/json Content-Type=application/json X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid} X-FromAppId=${GLOBAL_APPLICATION_ID} Authorization=Basic ${auth_string}
+ ${resp}= Delete Request ${alias} ${data_path} headers=${headers}
+ Log Received response from scheduler ${resp.text}
+ ${valid}= Split String ${valid_status_codes}
+ Validate Status ${resp} ${valid}
+ [Return] ${resp}
+
+Get Scheduler
+ [Documentation] Runs a scheduler GET request
+ [Arguments] ${alias} ${data_path}
+ ${url}= Catenate ${GLOBAL_SCHEDULER_PROTOCOL}://${GLOBAL_SCHEDULER_HOST}:${GLOBAL_SCHEDULER_PORT}
+ ${uuid}= Generate UUID
+ ${proxies}= Create Dictionary no=pass
+ ${session}= Create Session ${alias} ${url}
+ ${auth_string}= B64 Encode ${GLOBAL_SCHEDULER_USER}:${GLOBAL_SCHEDULER_PASSWORD}
+ ${headers}= Create Dictionary Accept=application/json Content-Type=application/json X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid} X-FromAppId=${GLOBAL_APPLICATION_ID} Authorization=Basic ${auth_string}
+ ${resp}= Get Request ${alias} ${data_path} headers=${headers}
+ Log Received response from scheduler ${resp.json()}
+ ${valid}= Split String ${valid_status_codes}
+ Validate Status ${resp} ${valid}
+ [Return] ${resp}
diff --git a/cmso-robot/robot/resources/scheduler_requests/approval_requests.robot b/cmso-robot/robot/resources/scheduler_requests/approval_requests.robot
new file mode 100644
index 0000000..c971017
--- /dev/null
+++ b/cmso-robot/robot/resources/scheduler_requests/approval_requests.robot
@@ -0,0 +1,36 @@
+*** Settings ***
+Documentation Scheduler keywords
+
+Library StringTemplater
+Library UUID
+Library DateTime
+Library Collections
+
+Resource ../scheduler_common.robot
+Resource ../json_templater.robot
+
+*** Variables ****
+${TEMPLATES} robot/assets/templates/changemanagement
+${UTC} %Y-%m-%dT%H:%M:%SZ
+
+*** Keywords ***
+Wait For Pending Approval
+ [Documentation] Gets the schedule identified by the uuid and checks if it is in the Pending Approval state
+ [Arguments] ${uuid} ${status}=Pending Approval
+ ${resp}= Get Change Management auth schedules/${uuid}
+ ${json}= Catenate ${resp.json()}
+ Dictionary Should Contain Item ${resp.json()} status ${status}
+
+Send Tier2 Approval
+ [Documentation] Sends an approval post request for the given schedule using the UUID and User given and checks that request worked
+ [Arguments] ${uuid} ${user} ${status}
+ ${approval}= Create Dictionary approvalUserId=${user} approvalType=Tier 2 approvalStatus=${status}
+ ${resp}= Post Change Management auth schedules/${uuid}/approvals data=${approval}
+ Should Be Equal As Strings ${resp.status_code} 204
+
+
+Send Invalid Approval
+ [Arguments] ${uuid} ${user}
+ ${approval}= Create Dictionary approvalUserId=${user} approvalType=Tier 3 approvalStatus=Accepted
+ Run Keyword and Expect Error 400 Post Change Management auth schedules/${uuid}/approvals data=${approval}
+ \ No newline at end of file
diff --git a/cmso-robot/robot/resources/scheduler_requests/create_schedule.robot b/cmso-robot/robot/resources/scheduler_requests/create_schedule.robot
new file mode 100644
index 0000000..7264b05
--- /dev/null
+++ b/cmso-robot/robot/resources/scheduler_requests/create_schedule.robot
@@ -0,0 +1,49 @@
+*** Settings ***
+Documentation SCheduler tests
+
+Library StringTemplater
+Library UUID
+Library String
+Library DateTime
+Library Collections
+Library OperatingSystem
+Library JSONUtils
+
+Resource ../scheduler_common.robot
+Resource ../json_templater.robot
+
+*** Variables ****
+${VID_TEMPLATES} robot/assets/templates/changemanagement
+${UTC} %Y-%m-%dT%H:%M:%SZ
+
+*** Keywords ***
+Create Schedule
+ [Arguments] ${uuid} ${request_file} ${TEMPLATES} ${workflow}=Unknown ${minutesFromNow}=5
+ ${testid}= Catenate ${uuid}
+ ${testid}= Get Substring ${testid} -4
+ ${dict}= Create Dictionary serviceInstanceId=${uuid} parent_service_model_name=${uuid}
+ ${callbackData}= Fill JSON Template File ${VID_TEMPLATES}/VidCallbackData.json.template ${dict}
+ ${callbackDataString}= Json Escape ${callbackData}
+ ${map}= Create Dictionary uuid=${uuid} callbackUrl=${GLOBAL_VID_CALLBACK_URL} callbackData=${callbackDataString} testid=${testid} workflow=${workflow} userId=${GLOBAL_VID_USERID}
+ ${nodelist}= Split String ${NODES} ,
+ ${nn}= Catenate 1
+ # Support up to 4 ChangeWindows
+ : For ${i} in range 1 4
+ \ ${today}= Evaluate ((${i}-1)*1440)+${minutesFromNow}
+ \ ${tomorrow} Evaluate ${today}+1440
+ \ ${last_time} Evaluate ${today}+30
+ \ ${start_time}= Get Current Date UTC + ${today} minutes result_format=${UTC}
+ \ ${end_time}= Get Current Date UTC + ${tomorrow} minutes result_format=${UTC}
+ \ Set To Dictionary ${map} start_time${i}=${start_time} end_time${i}=${end_time}
+
+ : For ${vnf} in @{nodelist}
+ \ Set To Dictionary ${map} node${nn} ${vnf}
+ \ ${nn}= Evaluate ${nn}+1
+
+
+ ${data}= Fill JSON Template File ${TEMPLATES}/${request_file} ${map}
+ ${resp}= Post Change Management auth schedules/${uuid} data=${data}
+ [Return] ${resp}
+
+
+ \ No newline at end of file
diff --git a/cmso-robot/robot/resources/test_templates/change_management.robot b/cmso-robot/robot/resources/test_templates/change_management.robot
new file mode 100644
index 0000000..0584cce
--- /dev/null
+++ b/cmso-robot/robot/resources/test_templates/change_management.robot
@@ -0,0 +1,166 @@
+*** Settings ***
+Documentation Creates VID VNF Instance
+Library StringTemplater
+Library String
+Library OperatingSystem
+Library UUID
+Library Collections
+Library HttpLibrary.HTTP
+Library DateTime
+Resource ../scheduler_common.robot
+Resource ../json_templater.robot
+Resource ../files.robot
+Resource ../scheduler_requests/create_schedule.robot
+Resource ../scheduler_requests/approval_requests.robot
+*** Variables ****
+#Variable can only be assigned String variables initially
+${status_list}=
+${expected_status_list_immediate}= "Scheduled","Notifications Initiated"
+${expected_status_list}= "Pending Schedule","Pending Approval","Scheduled","Notifications Initiated","Optimization in Progress"
+*** Keywords ***
+#GENERAL NOTES about Robot Framework
+# Keywords are effectively equivalent to functions/methods
+# ${} denotes a scalar variable @{} denotes a list variable and &{} denotes a Dictionary
+# Only scalar variables should be passed to a function. Even if your function calls for a list it is easier to pass the list in as a scalar ${}
+# To do this simply declare your non-scalar normally (@{}&{}), then when passing the non-scalar into a function pass it as a ${}
+#
+Change Management Template
+ [Arguments] ${request_file} ${expected_status_code} ${template_folder}
+ ${uuid}= Generate UUID
+ ${resp}= Create Schedule ${uuid} ${request_file} ${template_folder} #Sends the POST request to create schedule. Result stored in ${resp} resp is an object that comes from the RequestLibrary
+ Wait Until Keyword Succeeds 120s 5s Wait For Pending Approval ${uuid} #Runs Wait For Pending Approval every 5s for 120s or until it passes
+ Should Be Equal as Strings ${resp.status_code} ${expected_status_code} #This will fail if an unexpected result is received from Scheduler
+ Send Tier2 Approval ${uuid} jf9860 Accepted
+ ${resp}= Get Change Management auth schedules/${uuid} #GETs the schedule from Scheduler. The result is stored in $resp
+ Wait Until Keyword Succeeds 120s 5s Wait For All VNFs Reach Status Completed ${uuid} #Makes sure VNF(s) is(are) completed in the schedule
+ Wait Until Keyword Succeeds 120s 5s Wait for Schedule to Complete Completed ${uuid} #Makes sure Schedule is marked completed
+ ${reps}= Delete Change Management auth schedules/${uuid} #sends DELETE request to scheduler this may have to be changed for 1802 US to change Delete Schedule to Cancel Schedule
+
+Change Management Rejection Template
+ [Arguments] ${request_file} ${template_folder}
+ ${uuid}= Generate UUID
+ ${expected_status_code}= Convert to String 202 #Variables in keywords section have to be assigned keywords. So ${expected_status_code}= 202
+ ${resp}= Create Schedule ${uuid} ${request_file} ${template_folder}
+ Wait Until Keyword Succeeds 120s 5s Wait For Pending Approval ${uuid}
+ Should Be Equal as Strings ${resp.status_code} ${expected_status_code}
+ Send Tier2 Approval ${uuid} jf9860 Rejected #Sends and checks Approval POST request
+
+Change Management Failure Template
+ [Documentation] Sends a post request expecting a failure. expected_status_code should be whatever code is expected for this call
+ [Arguments] ${request_file} ${expected_status_code} ${template_folder}
+ ${uuid}= Generate UUID
+ ${resp}= Create Schedule ${uuid} ${request_file} ${template_folder}
+ Should Be Equal as Strings ${resp.status_code} ${expected_status_code}
+ Return from Keyword If '${resp.status_code}' == '202'
+ #List of possible reasons that the request should fail - we should look for exact message.....
+ @{status_list}= Create List Scheduler.INVALID_ATTRIBUTE Scheduler.MISSING_REQUIRED_ATTRIBUTE Scheduler.NODE_LIST_CONTAINS_EMTPY_NODE Scheduler.INVALID_CHANGE_WINDOW
+ Validate Json Error ${resp.json()} ${status_list}
+
+Change Management Immediate Template
+ [Arguments] ${request_file} ${expected_status_code} ${template_folder}
+ ${uuid}= Generate UUID
+ ${resp}= Create Schedule ${uuid} ${request_file} ${template_folder} #Immediate schedules do not need approval so there is no wait for pending approval or send approval
+ Should Be Equal as Strings ${resp.status_code} ${expected_status_code}
+ Wait Until Keyword Succeeds 120s 5s Wait For All VNFs Reach Status Completed ${uuid}
+ Wait Until Keyword Succeeds 120s 5s Wait for Schedule to Complete Completed ${uuid}
+ ${reps}= Delete Change Management auth schedules/${uuid}
+Change Management Already Exists Immediate Template
+ [Arguments] ${request_file} ${template_folder}
+ ${uuid}= Convert to String 46969fb7-0d4c-4e78-80ca-e20759628be5 #This value was taken from DEV env Scheduler DB. To actually automate may want to make SQL query Keyword to get an existing scheduleId
+ ${resp}= Create Schedule ${uuid} ${request_file} ${template_folder}
+ Should Be Equal as Strings ${resp.status_code} 409
+Record Status Immediate Template
+ [Arguments] ${request_file} ${template_folder}
+ ${uuid}= Generate UUID
+ ${resp}= Create Schedule ${uuid} ${request_file} ${template_folder}
+ Set Global Variable ${status_list} ${EMPTY} #$EMPTY is a empty string variable defined by ROBOT. This makes sure the global variable is cleared each run
+ Wait Until Keyword Succeeds 120s 5s Add to Status List Completed ${uuid}
+ ${reps}= Delete Change Management auth schedules/${uuid}
+ Compare Status List ${expected_status_list_immediate} ${status_list}
+ Log ${status_list}
+Record Status Template
+ [Documentation] This test checks statuses for future schedules. It tends to fail due to scheduled status being missed.
+ [Arguments] ${request_file} ${template_folder}
+ ${uuid}= Generate UUID
+ ${resp}= Create Schedule ${uuid} ${request_file} ${template_folder}
+ Set Global Variable ${status_list} ${EMPTY}
+ Wait Until Keyword Succeeds 120s 5s Add to Status List Pending Approval ${uuid}
+ Send Tier2 Approval ${uuid} jf9860 Accepted
+ ${resp}= Get Change Management auth schedules/${uuid}
+ Wait Until Keyword Succeeds 300s 5s Wait For All VNFs Reach Status and Add to Status Completed ${uuid}
+ ${reps}= Delete Change Management auth schedules/${uuid}
+ Compare Status List ${expected_status_list} ${status_list}
+ Log ${status_list}
+#Check Status Template
+# [Arguments] ${request_file} ${template_folder}
+# ${uuid}= Generate UUID
+# ${resp}= Create Schedule ${uuid} ${request_file} ${template_folder}
+# Check Schedule Status Pending Schedule ${uuid}
+
+Get Schedule Test Template
+ [Documentation] This function reads scheduleIds and the expected values from a text file (see robot/assets/get_schedule_UUIDs.txt for the format) then runs a get on them to confirm the GET schedule functionality #this could be enhanced with SQL query to db
+ [Arguments] ${existing_uuid_file}
+ ${uuid_file}= OperatingSystem.Get File ${existing_uuid_file} #this file works with the dev server as of 11/9/2017
+ @{file_lines}= Split to Lines ${uuid_file}
+ &{uuid_dictionary}= Create Dictionary
+ :For ${line} in @{file_lines}
+ \ @{line_array}= Split String ${line}
+ \ log ${line_array[1]}
+ \ Set To Dictionary ${uuid_dictionary} @{line_array}[0] @{line_array}[1] #You can pass singular list items as scalar variables
+ \
+ Log ${uuid_dictionary}
+ @{resp_list}= Create List
+ :For ${uuid} in @{uuid_dictionary.keys()}
+ \ ${resp}= Get Change Management auth schedules/${uuid}
+ \ ${actual_status}= Get from dictionary ${uuid_dictionary} ${uuid}
+ \ Should be equal as Strings ${actual_status} ${resp.status_code}
+ \ Run Keyword If ${resp.status_code} == 200 Dictionary should contain key ${resp.json()} status ELSE Dictionary Should Contain Key ${resp.json()['requestError']} messageId #${resp.json()['requestError']} this is a scalar reference to a singular item from a dictionary.
+ \ Append to List ${resp_list} ${resp.json()}
+ Log ${resp_list}
+Wait For All VNFs Reach Status
+ [Documentation] Checks the status of the VNFs in a schedule.
+ [Arguments] ${status} ${uuid}
+ ${resp}= Get Change Management auth schedules/scheduleDetails?request.scheduleId=${uuid}
+ : for ${vnf} in @{resp.json()}
+ \ Dictionary Should Contain Item ${vnf} status Completed
+Wait For All VNFs Reach Status and Add to Status
+ [Documentation] This records the status of the vnf in the global status list
+ [Arguments] ${status} ${uuid}
+ ${resp}= Get Change Management auth schedules/scheduleDetails?request.scheduleId=${uuid}
+ : for ${vnf} in @{resp.json()}
+ \ Dictionary Should Contain Item ${vnf} status Completed
+ Add to Status List Completed ${uuid} #This only runs if there are no failures in Dictionary should Contain Item for loop previously
+Wait for Schedule to Complete
+ [Documentation] This is used in wait for keyword to succeed generally it checks if the status of the schedule returned by a GET request is Complete
+ [Arguments] ${status} ${uuid}
+ ${resp}= Get Change Management auth schedules/${uuid}
+ Dictionary Should Contain Item ${resp.json()} status Completed
+#Check Schedule Status
+# [Arguments] ${status} ${uuid}
+# ${resp}= Get Change Management auth schedules/${uuid}
+# Dictionary Should Contain Item ${resp.json()} status ${status}
+Add To Status List
+ [Documentation] Takes List and Schedule ID and changes global list of Statuses #A global list was used because Wait for Keyword to Succeed only seems to return pass or fail
+ [Arguments] ${end_status} ${uuid}
+ ${resp}= Get Change Management auth schedules/${uuid}
+ ${json}= Stringify Json ${resp.json()}
+ ${status}= Get Json Value ${json} /status
+ ${temp_list}= Catenate ${status_list} ${status},
+ ${temp_list}= Replace String ${temp_list} ${SPACE}" ${EMPTY}"
+ Set Global Variable ${status_list} ${temp_list}
+ Should Contain ${status} ${end_status}
+Compare Status List
+ [Arguments] ${expected} ${actual}
+ @{expected_list}= Split String ${expected} ,
+ @{actual_list}= Split String ${actual} ,
+ :For ${current} in @{expected_list}
+ \ Should Contain ${actual_list} ${current}
+
+Change Management DB Failover Template
+ [Arguments] ${request_file} ${template_folder} ${uuid1} ${uuid2}
+ Set Global Variable ${NODES} ${uuid1}
+ Run Keyword If '${uuid2}' != 'None' Delete Change Management auth schedules/${uuid2} #Sends and checks Approval POST request
+ ${expected_status_code}= Convert to String 202 #Variables in keywords section have to be assigned keywords. So ${expected_status_code}= 202
+ ${resp}= Create Schedule ${uuid1} ${request_file} ${template_folder}
+ Wait Until Keyword Succeeds 120s 5s Wait For Pending Approval ${uuid1} Optimization Failed
+ Should Be Equal as Strings ${resp.status_code} ${expected_status_code}
diff --git a/cmso-robot/robot/resources/test_templates/change_management_ete.robot b/cmso-robot/robot/resources/test_templates/change_management_ete.robot
new file mode 100644
index 0000000..74dfdc2
--- /dev/null
+++ b/cmso-robot/robot/resources/test_templates/change_management_ete.robot
@@ -0,0 +1,84 @@
+*** Settings ***
+Documentation Creates VID VNF Instance
+
+Library StringTemplater
+Library UUID
+Library Collections
+Library SSHLibrary
+
+Resource ../scheduler_common.robot
+Resource ../json_templater.robot
+Resource ../scheduler_requests/create_schedule.robot
+Resource ../scheduler_requests/approval_requests.robot
+
+*** Variables ****
+${TEMPLATES} robot/assets/templates
+
+*** Keywords ***
+Change Management Template
+ [Arguments] ${request_file} ${workflow} ${minutesFromNow}=1
+ ${template_folder}= Catenate ${TEMPLATES}/changemanagement
+ ${uuid}= Generate UUID
+ ${resp}= Create Schedule ${uuid} ${request_file} ${template_folder} workflow=${workflow} minutesFromNow=${minutesFromNow}
+ Should Be Equal as Strings ${resp.status_code} 202
+ Validate Acknowledgment Response Headers ${resp}
+ Wait Until Keyword Succeeds 600s 30s Wait For Pending Approval ${uuid}
+ Send Tier2 Approval ${uuid} jf9860 Accepted
+ ${resp}= Get Change Management auth schedules/${uuid}
+ Wait Until Keyword Succeeds 120s 30s Wait For All VNFs Reach Status Completed ${uuid}
+ Wait Until Keyword Succeeds 120s 30s Wait for Schedule to Complete Completed ${uuid}
+ ${reps}= Delete Change Management auth schedules/${uuid}
+
+Change Management Immediate Template
+ [Arguments] ${request_file} ${workflow}
+ ${template_folder}= Catenate ${TEMPLATES}/changemanagement
+ ${uuid}= Generate UUID
+ ${resp}= Create Schedule ${uuid} ${request_file} ${template_folder} workflow=${workflow}
+ Should Be Equal as Strings ${resp.status_code} 202
+ Validate Acknowledgment Response Headers ${resp}
+ Wait Until Keyword Succeeds 120s 30s Wait For All VNFs Reach Status Completed ${uuid}
+ Wait Until Keyword Succeeds 120s 30s Wait for Schedule to Complete Completed ${uuid}
+ ${reps}= Delete Change Management auth schedules/${uuid}
+
+Wait For All VNFs Reach Status
+ [Arguments] ${status} ${uuid}
+ ${resp}= Get Change Management auth schedules/scheduleDetails?request.scheduleId=${uuid}
+ : for ${vnf} in @{resp.json()}
+ \ Dictionary Should Contain Item ${vnf} status Completed
+
+Wait for Schedule to Complete
+ [Arguments] ${status} ${uuid}
+ ${resp}= Get Change Management auth schedules/${uuid}
+ Dictionary Should Contain Item ${resp.json()} status Completed
+
+Create and Approve
+ [Arguments] ${request_file} ${workflow} ${minutesFromNow}=5
+ ${template_folder}= Catenate ${TEMPLATES}/changemanagement
+ ${uuid}= Generate UUID
+ ${resp}= Create Schedule ${uuid} ${request_file} ${template_folder} workflow=${workflow} minutesFromNow=${minutesFromNow}
+ Should Be Equal as Strings ${resp.status_code} 202
+ Validate Acknowledgment Response Headers ${resp}
+ Wait Until Keyword Succeeds 300s 5s Wait For Pending Approval ${uuid}
+ Send Tier2 Approval ${uuid} jf9860 Accepted
+
+Change Management Cancel Template
+ [Arguments] ${request_file} ${workflow} ${minutesFromNow}=5
+ ${template_folder}= Catenate ${TEMPLATES}/changemanagement
+ ${uuid}= Generate UUID
+ ${resp}= Create Schedule ${uuid} ${request_file} ${template_folder} workflow=${workflow} minutesFromNow=${minutesFromNow}
+ Should Be Equal as Strings ${resp.status_code} 202
+ Validate Acknowledgment Response Headers ${resp}
+ Wait Until Keyword Succeeds 600s 5s Wait For Pending Approval ${uuid}
+ Send Tier2 Approval ${uuid} jf9860 Accepted
+ ${resp}= Delete Change Management auth schedules/${uuid}
+ Should Be Equal as Strings ${resp.status_code} 204
+ Log ${resp.headers}
+
+Validate Acknowledgment Response Headers
+ [Arguments] ${Response}
+ Log ${Response.headers}
+ ${act_headers_keys} = Get Dictionary Keys ${Response.headers}
+ Dictionary Should Contain Key ${Response.headers} X-LatestVersion
+ Dictionary Should Contain Key ${Response.headers} X-MinorVersion
+ Dictionary Should Contain Key ${Response.headers} X-PatchVersion
+ \ No newline at end of file
diff --git a/cmso-robot/robot/resources/test_templates/check_logs.robot b/cmso-robot/robot/resources/test_templates/check_logs.robot
new file mode 100644
index 0000000..5926caa
--- /dev/null
+++ b/cmso-robot/robot/resources/test_templates/check_logs.robot
@@ -0,0 +1,95 @@
+*** Settings ***
+Documentation Tests for checking ECOMP Scheduler Logs
+
+Library UUID
+Library SSHLibrary
+Library String
+
+
+Resource ../files.robot
+Resource ../scheduler_requests/create_schedule.robot
+Resource ../scheduler_requests/approval_requests.robot
+Resource ../json_templater.robot
+*** Variables ****
+${log_location}= /opt/app/ecomp-scheduler/logs/
+${debug_log_location}= /opt/app/ecomp-scheduler/debug-logs/
+${date_time_regex}= ((([0-9]{2,4}-?){3}.([0-9]{2}:?){3}.*))
+${uuid_regex}= [0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}
+
+*** Keywords ***
+#GENERAL Notes this
+Check Audit Logs
+ [Documentation] This test runs Create, Get, and Delete Schedule then checks logs in the server for the result
+ [Arguments] ${user-id} ${user-pass} ${request_file} ${template_folder}
+ ${uuid}= Generate UUID
+ ${resp}= Create Schedule ${uuid} ${request_file} ${template_folder}
+ ${resp}= Get Change Management auth schedules/${uuid}
+ ${resp}= Delete Change Management auth schedules/${uuid}
+ ${server}= Convert to String mtanjv9sdlg10 #This should not be hardcoded. From test_properties.py replace this with some modification of GLOBAL_SCHEDULER_HOST
+ ${log_level}= Convert to String (INFO|WARN|ERROR|FATAL)
+ ${log_msg}= Convert to String (Accepted|No Content|OK)
+ ${status_codes}= Convert to String (204|202|200)
+ ${audit_regex}= Convert to String \\|UNKNOWN\\|.*\\|ecomp-scheduler\\|.*\\|COMPLETE\\|${status codes}\\|${log_msg}\\|${uuid_regex}\\|${log_level}\\|.*\\|[0-9]{1,}\\|${server}\\|.*
+ #THis regex string follows the current expected audit.log structure logging guidelines as of 1710 here https://wiki.web.att.com/pages/viewpage.action?pageId=545861390
+ Open Connection ${GLOBAL_SCHEDULER_HOST} port=22
+ Login ${user-id} ${user-pass} #This may only work with dev server should investigate using Pageant with Robot
+ ${result}= Grep Local File -E '${date_time_regex}{2}\\|${uuid}${audit_regex}CREATE_SCHEDULE_REQUEST' ${log_location}audit.log
+ @{create_grep_result}= Split to Lines ${result}
+ ${result}= Grep Local File -E '${date_time_regex}{2}\\|${uuid}${audit_regex}GET_SCHEDULE_REQUEST' ${log_location}audit.log
+ @{get_grep_result}= Split to Lines ${result}
+ ${result}= Grep Local File -E '${date_time_regex}{2}\\|${uuid}${audit_regex}DELETE_SCHEDULE_REQUEST' ${log_location}audit.log
+ @{delete_grep_result}= Split to Lines ${result}
+ Close Connection
+ Log many ${create_grep_result} ${get_grep_result} ${delete_grep_result}
+ Should Contain ${create_grep_result}[1] Accepted #This is only present in logs for create schedule
+ Should Contain ${get_grep_result}[1] OK #This is only present in logs for get schedule
+ Should Contain ${delete_grep_result}[1] No Content #This is only present in logs for delete
+
+
+Check Debug Logs
+ [Arguments] ${user-id} ${user-pass} ${request_file} ${template_folder}
+ ${uuid}= Generate UUID
+ ${resp}= Create Schedule ${uuid} ${request_file} ${template_folder}
+ ${resp}= Get Change Management auth schedules/${uuid}
+ ${resp}= Delete Change Management auth schedules/${uuid}
+ Open Connection ${GLOBAL_SCHEDULER_HOST} port=22
+ Login ${user-id} ${user-pass}
+ ${result}= Grep Local File -E '${date_time_regex}\\|${uuid}' /opt/app/ecomp-scheduler/debug-logs/debug.log
+ #THis regex string follows the current expected debug.log structure logging guidelines as of 1710 here https://wiki.web.att.com/pages/viewpage.action?pageId=545861390
+ Close Connection
+ Should not be Empty ${result}
+
+Check Metric Logs
+ [Arguments] ${user-id} ${user-pass} ${request_file} ${template_folder}
+ ${uuid}= Generate UUID
+ ${resp}= Create Schedule ${uuid} ${request_file} ${template_folder}
+ ${resp}= Get Change Management auth schedules/${uuid}
+ ${resp}= Delete Change Management auth schedules/${uuid}
+ ${server}= Convert to String mtanjv9sdlg10
+ ${log_level}= Convert to String (INFO|WARN|ERROR|FATAL)
+ ${log_msg}= Convert to String (Accepted|No Content|OK|[a-zA-Z]+)
+ ${status_codes}= Convert to String (204|202|200)
+ ${regex}= Convert To String \\|UNKNOWN\\|.*\\|ecomp-scheduler\\|.*\\|http://([a-zA-Z]*\.){2,}(:[0-9]{1,5})?\\|(.*/?){1,}\\|COMPLETE\\|${status codes}\\|${log_msg}\\|${uuid_regex}\\|${log_level}\\|.*\\|[0-9]{1,}\\|${server}\\|.*
+ #THis regex string follows the current expected metric.log structure logging guidelines as of 1710 here https://wiki.web.att.com/pages/viewpage.action?pageId=545861390
+ Open Connection ${GLOBAL_SCHEDULER_HOST} port=22
+ Login ${user-id} ${user-pass}
+ ${result}= Grep Local File '${date_time_regex}{2}\\|${uuid}${regex}' ${log_location}metrics.log
+ @{grep_result}= Split to Lines ${result}
+ Close Connection
+ Should Not be Empty ${grep_result}
+ Log ${grep_result}
+
+
+Check Error Logs
+ [Arguments] ${user-id} ${user-pass} ${request_file} ${template_folder}
+
+ Open Connection ${GLOBAL_SCHEDULER_HOST} port=22
+ Login ${user-id} ${user-pass}
+ ${result}= Grep Local File '${date_time_regex}\\|${uuid_regex}\\|.*\\|ecomp-scheduler\\|.*\\|.*(WARN|ERROR|FATAL).*\\|.*\\|' ${log_location}error.log
+ #THis regex string follows the current expected error.log structure logging guidelines as of 1710 here https://wiki.web.att.com/pages/viewpage.action?pageId=545861390
+ #It is difficult to generate errors that would be logged in error.log. so this only tests that any error in the log matches the expected format
+ @{grep_result}= Split to Lines ${result}
+ Close Connection
+ Should Not be Empty ${grep_result}
+ Log ${grep_result}
+ \ No newline at end of file
diff --git a/cmso-robot/robot/resources/vtm_common.robot b/cmso-robot/robot/resources/vtm_common.robot
new file mode 100644
index 0000000..08061f5
--- /dev/null
+++ b/cmso-robot/robot/resources/vtm_common.robot
@@ -0,0 +1,93 @@
+*** Settings ***
+Documentation The private interface for interacting with Openstack. It handles low level stuff like managing the authtoken and Openstack required fields
+
+Library Collections
+Library RequestsLibrary
+Library UUID
+Library HTTPUtils
+Library DateTime
+
+Resource misc.robot
+*** Variables ***
+*** Variables ***
+# http://zld03290.vci.att.com:9018
+#
+${CLOSE_PATH} /vtm/manageChangeRecord/v1/closeCancelChangeRecord
+${CLOSE_PORT} 31127
+
+
+#**************** Test Case Variables ******************
+
+*** Keywords ***
+
+vTM Query Template
+ [Documentation]
+ [Arguments] ${alias} ${offset}=0 ${numOfrows}=100 ${display}=[] ${filter}={}
+ ${request}= Create Dictionary offset=${offset} numOfRows=${numOfRows} displayTuple=${display} filterTuple=${filter}
+ Log ${request}
+ ${resp}= vTM Query ${alias} ${request}
+ [Return] ${resp}
+
+
+vTM Query
+ [Documentation]
+ [Arguments] ${alias} ${request}
+ ${url}= Catenate ${GLOBAL_VTM_URL}
+ ${data_path}= Catenate ${GLOBAL_LISTCHANGE_PATH}
+ ${uuid}= Generate UUID
+ ${proxies}= Create Dictionary no=pass
+ ${session}= Create Session ${alias} ${url} verify=True
+ ${auth_string}= B64 Encode ${GLOBAL_VTM_USER}:${GLOBAL_VTM_PASSWORD}
+ #Authorization=Basic ${GLOBAL_POLICY_AUTH} ClientAuth=${GLOBAL_POLICY_CLIENTAUTH}
+ ${headers}= Create Dictionary Authorization=Basic ${auth_string} Accept=application/json Content-Type=application/json X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid} X-FromAppId=${GLOBAL_APPLICATION_ID}
+ ${resp}= Post Request ${alias} ${data_path} headers=${headers} data=${request}
+ Log Received response from vTM ${resp.text}
+ ${valid}= Create List 200 404
+ Validate Status ${resp} ${valid}
+ [Return] ${resp}
+
+
+vTM Close Ticket
+ [Documentation]
+ [Arguments] ${alias} ${ticket} ${changeClosedBy}=jf9860
+ ${url}= Catenate ${GLOBAL_VTM_PROTO}://${GLOBAL_VTM_HOST}:${CLOSE_PORT}
+ ${data_path}= Catenate ${CLOSE_PATH}
+ ${uuid}= Generate UUID
+ ${proxies}= Create Dictionary no=pass
+ ${session}= Create Session ${alias} ${url} verify=True
+ ${auth_string}= B64 Encode ${GLOBAL_VTM_USER}:${GLOBAL_VTM_PASSWORD}
+ ${end}= Get Current Date result_format=epoch exclude_millis=True
+ ${end}= Convert To Integer ${end}
+ ${start}= Evaluate ${end}-60
+ ${request}= Create Dictionary changeId=${ticket} status=Closed changeClosedBy=${changeClosedBy} closureCode=Successful As Scheduled
+ Set To Dictionary ${request} customerImpacted=Unknown actualStartDate=${start} actualEndDate=${end}
+
+ #Authorization=Basic ${GLOBAL_POLICY_AUTH} ClientAuth=${GLOBAL_POLICY_CLIENTAUTH}
+ ${headers}= Create Dictionary Authorization=Basic ${auth_string} Accept=application/json Content-Type=application/json X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid} X-FromAppId=${GLOBAL_APPLICATION_ID}
+ ${resp}= Post Request ${alias} ${data_path} headers=${headers} data=${request}
+ Log Received response from vTM ${resp.json()}
+ ${valid}= Create List 200 404
+ Validate Status ${resp} ${valid}
+ [Return] ${resp}
+
+
+vTM Cancel Ticket
+ [Documentation]
+ [Arguments] ${alias} ${ticket}
+ ${url}= Catenate ${GLOBAL_VTM_PROTO}://${GLOBAL_VTM_HOST}:${CLOSE_PORT}
+ ${data_path}= Catenate ${CLOSE_PATH}
+ ${uuid}= Generate UUID
+ ${proxies}= Create Dictionary no=pass
+ ${session}= Create Session ${alias} ${url} verify=True
+ ${auth_string}= B64 Encode ${GLOBAL_VTM_USER}:${GLOBAL_VTM_PASSWORD}
+ ${end}= Get Current Date result_format=epoch exclude_millis=True
+ ${end}= Convert To Integer ${end}
+ ${start}= Evaluate ${end}-60
+ ${request}= Create Dictionary changeId=${ticket} status=Closed changeClosedBy=${GLOBAL_VID_USERID} closureCode=Cancelled closingComments=Cancel requested by user
+ Set To Dictionary ${request} customerImpacted=No
+ ${headers}= Create Dictionary Authorization=Basic ${auth_string} Accept=application/json Content-Type=application/json X-TransactionId=${GLOBAL_APPLICATION_ID}-${uuid} X-FromAppId=${GLOBAL_APPLICATION_ID}
+ ${resp}= Post Request ${alias} ${data_path} headers=${headers} data=${request}
+ Log Received response from vTM ${resp.json()}
+ ${valid}= Create List 200 404
+ Validate Status ${resp} ${valid}
+ [Return] ${resp}
diff --git a/cmso-robot/robot/testsuites/ChangeManagementCancel.robot b/cmso-robot/robot/testsuites/ChangeManagementCancel.robot
new file mode 100644
index 0000000..ad193f6
--- /dev/null
+++ b/cmso-robot/robot/testsuites/ChangeManagementCancel.robot
@@ -0,0 +1,24 @@
+*** Settings ***
+Documentation Creates VID VNF Instance
+
+Library StringTemplater
+Library UUID
+
+Resource ../resources/test_templates/change_management_ete.robot
+
+# Test Setup
+Test Template Change Management Cancel Template
+# Test Teardown
+
+*** Test Cases ***
+One VNF One Change Window OneVnfOneChangeWindow.json.template Replace minutesFromNow=20
+ [Tags] ete future
+
+Multiple VNFs One Change Window OneGroupMultipleVNFsOneChangeWindow.json.template Replace minutesFromNow=20
+ [Tags] ete future
+
+Multiple VNFs Two Change Windows OneGroupMultipleVNSsTwoChangeWindows.json.template Replace minutesFromNow=20
+ [Tags] ete future
+
+One VNF One Change Window Update OneVnfOneChangeWindow.json.template Update minutesFromNow=20
+ [Tags] ete future
diff --git a/cmso-robot/robot/testsuites/ChangeManagementDBFailover.robot b/cmso-robot/robot/testsuites/ChangeManagementDBFailover.robot
new file mode 100644
index 0000000..a951145
--- /dev/null
+++ b/cmso-robot/robot/testsuites/ChangeManagementDBFailover.robot
@@ -0,0 +1,25 @@
+*** Settings ***
+Documentation Creates VID VNF Instance
+
+Library StringTemplater
+Library UUID
+
+Resource ../resources/test_templates/change_management.robot
+
+# Test Setup
+Test Template Change Management DB Failover Template
+# Test Teardown
+*** Variable***
+${status_code_variable}= 202
+${template_folder}= robot/assets/templates/changemanagement
+*** Test Cases ***
+Step 2 OneVnfOneChangeWindowReplaceVNFInfra.json.template ${template_folder} e2e006 None
+
+Step 5 OneVnfOneChangeWindowReplaceVNFInfra.json.template ${template_folder} e2e002 e2e001
+
+Step 9 OneVnfOneChangeWindowReplaceVNFInfra.json.template ${template_folder} e2e003 e2e002
+
+Step 13 OneVnfOneChangeWindowReplaceVNFInfra.json.template ${template_folder} e2e004 e2e003
+
+
+
diff --git a/cmso-robot/robot/testsuites/ChangeManagementFailure.robot b/cmso-robot/robot/testsuites/ChangeManagementFailure.robot
new file mode 100644
index 0000000..5e74105
--- /dev/null
+++ b/cmso-robot/robot/testsuites/ChangeManagementFailure.robot
@@ -0,0 +1,57 @@
+*** Settings ***
+Documentation Creates VID VNF Instance
+
+Library StringTemplater
+Library UUID
+Library OperatingSystem
+Resource ../resources/test_templates/change_management.robot
+
+# Test Setup
+Test Template Change Management Failure Template
+# Test Teardown
+*** Variable ***
+${status_code_variable}= 400
+${template_folder}= robot/assets/templates/FailureCasesChangeManagement
+*** Test Cases ***
+# This for loop will generate a test for each file. It has been replaced by GenerateRobot.py which generates something similar to the below cases
+# This was done because all tests run by the for loop counted as a single test and could not be tagged individually
+#@{Global_cm...} may show as an error but it still seems to work I guess
+#One VNF One Change Window ete failure
+# :FOR ${current_template_file} IN @{GLOBAL_CM_ete failure_TEMPLATES}
+# \ ${current_template_file} ${status_code_variable} ${template_folder}
+
+One Vnf One Change Window Empty Domain OneVnfOneChangeWindowEmptyDomain.json.template ${status_code_variable} ${template_folder}
+ [Tags] ete failure future single VNF single window
+
+One Vnf One Change Window Empty Schedule ID OneVnfOneChangeWindowEmptyScheduleID.json.template ${status_code_variable} ${template_folder}
+ [Tags] ete failure future single VNF single window
+
+## Schedule name is now optional
+One Vnf One Change Window Empty Schedule Name OneVnfOneChangeWindowEmptyScheduleName.json.template 202 ${template_folder}
+ [Tags] ete failure future single VNF single window
+
+One Vnf One Change Window Empty User ID OneVnfOneChangeWindowEmptyUserID.json.template ${status_code_variable} ${template_folder}
+ [Tags] ete failure future single VNF single window
+
+## Policies are validated by SNIRO
+One Vnf One Change Window Incorrect Policy Id OneVnfOneChangeWindowIncorrectPolicyId.json.template 202 ${template_folder}
+ [Tags] ete failure future single VNF single window
+
+## 1806 allow for unknown workflows
+One Vnf One Change Window Incorrect Workflow OneVnfOneChangeWindowIncorrectWorkflow.json.template 202 ${template_folder}
+ [Tags] ete failure future single VNF single window
+
+One Vnf One Change Window Negative Normal Duration In Seconds OneVnfOneChangeWindowNegativeNormalDurationInSeconds.json.template ${status_code_variable} ${template_folder}
+ [Tags] ete failure future single VNF single window
+
+One Vnf One Change Window No End Time OneVnfOneChangeWindowNoEndTime.json.template ${status_code_variable} ${template_folder}
+ [Tags] ete failure future single VNF single window
+
+One Vnf One Change Window No Node Name OneVnfOneChangeWindowNoNodeName.json.template ${status_code_variable} ${template_folder}
+ [Tags] ete failure future single VNF single window
+
+One Vnf One Change Window No Start Time OneVnfOneChangeWindowNoStartTime.json.template ${status_code_variable} ${template_folder}
+ [Tags] ete failure future single VNF single window
+
+One Vnf One Change Window Switched Time OneVnfOneChangeWindowSwitchedTime.json.template ${status_code_variable} ${template_folder}
+ [Tags] ete failure future single VNF single window
diff --git a/cmso-robot/robot/testsuites/ChangeManagementFuture.robot b/cmso-robot/robot/testsuites/ChangeManagementFuture.robot
new file mode 100644
index 0000000..5dad749
--- /dev/null
+++ b/cmso-robot/robot/testsuites/ChangeManagementFuture.robot
@@ -0,0 +1,24 @@
+*** Settings ***
+Documentation Creates VID VNF Instance
+
+Library StringTemplater
+Library UUID
+
+Resource ../resources/test_templates/change_management_ete.robot
+
+# Test Setup
+Test Template Change Management Template
+# Test Teardown
+
+*** Test Cases ***
+One VNF One Change Window OneVnfOneChangeWindow.json.template Replace
+ [Tags] ete future
+
+Multiple VNFs One Change Window OneGroupMultipleVNFsOneChangeWindow.json.template Replace
+ [Tags] ete future
+
+Multiple VNFs Two Change Windows OneGroupMultipleVNSsTwoChangeWindows.json.template Replace
+ [Tags] ete future
+
+One VNF One Change Window Update OneVnfOneChangeWindow.json.template Update
+ [Tags] ete future
diff --git a/cmso-robot/robot/testsuites/ChangeManagementImmediate.robot b/cmso-robot/robot/testsuites/ChangeManagementImmediate.robot
new file mode 100644
index 0000000..f7e399a
--- /dev/null
+++ b/cmso-robot/robot/testsuites/ChangeManagementImmediate.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Documentation Creates VID VNF Instance
+
+Library StringTemplater
+Library UUID
+
+Resource ../resources/test_templates/change_management_ete.robot
+
+# Test Setup
+Test Template Change Management Immediate Template
+# Test Teardown
+
+*** Test Cases ***
+One Vnf Immediate Replace OneVnfImmediate.json.template Replace
+ [Tags] ete immediate
+
+One Vnf Immediate Update Config OneVnfImmediate.json.template VNF Config Update
+ [Tags] ete immediate
+
+One Vnf Immediate Update In Place OneVnfImmediate.json.template VNF Update Software In Place
+ [Tags] ete immediate
+
+One Vnf Immediate Update OneVnfImmediate.json.template Update
+ [Tags] ete immediate
+
+Multiple Vnf Immediate MultipleVnfImmediate.json.template Replace
+ [Tags] ete immediate
diff --git a/cmso-robot/robot/testsuites/ChangeManagementImmediateFailure.robot b/cmso-robot/robot/testsuites/ChangeManagementImmediateFailure.robot
new file mode 100644
index 0000000..74f1959
--- /dev/null
+++ b/cmso-robot/robot/testsuites/ChangeManagementImmediateFailure.robot
@@ -0,0 +1,52 @@
+*** Settings ***
+Documentation Creates VID VNF Instance
+
+Library StringTemplater
+Library UUID
+Library OperatingSystem
+Resource ../resources/test_templates/change_management.robot
+
+# Test Setup
+Test Template Change Management Failure Template
+# Test Teardown
+*** Variable ***
+${status_code_variable}= 400
+${one_vnf_template_folder}= robot/assets/templates/OneVNFImmediateFailureCases
+${multiple_vnf_template_folder}= robot/assets/templates/MutipleVNFImmediateFailureCases
+*** Test Cases ***
+#@{Global_cm...} may show as an error but it still seems to work I guess
+#One VNF Immediate Failure
+# :FOR ${current_template_file} IN @{GLOBAL_CM_ONEVNF_FAILURE_TEMPLATES}
+# \ ${current_template_file} ${status_code_variable} ${one_vnf_template_folder}
+
+#Multiple VNF Immediate Failure
+# :FOR ${current_template_file} IN @{GLOBAL_CM_MULTIPLE_VNF_FAILURE_TEMPLATES}
+# \ ${current_template_file} ${status_code_variable} ${multiple_vnf_template_folder}
+
+One Vnf Immediate Empty Domain OneVnfImmediateEmptyDomain.json.template ${status_code_variable} ${one_vnf_template_folder}
+ [Tags] ete failure immediate single VNF
+
+One Vnf Immediate Empty Schedule Id OneVnfImmediateEmptyScheduleId.json.template ${status_code_variable} ${one_vnf_template_folder}
+ [Tags] ete failure immediate single VNF
+
+## schedule name is now optional
+One Vnf Immediate Empty Schedule Name OneVnfImmediateEmptyScheduleName.json.template 202 ${one_vnf_template_folder}
+ [Tags] ete failure immediate single VNF
+
+One Vnf Immediate Empty Scheduling Info OneVnfImmediateEmptySchedulingInfo.json.template ${status_code_variable} ${one_vnf_template_folder}
+ [Tags] ete failure immediate single VNF
+
+One Vnf Immediate Empty User Id OneVnfImmediateEmptyUserId.json.template ${status_code_variable} ${one_vnf_template_folder}
+ [Tags] ete failure immediate single VNF
+
+Multiple Vnf Immediate Empty Domain MultipleVnfImmediateEmptyDomain.json.template ${status_code_variable} ${multiple_vnf_template_folder}
+ [Tags] ete failure immediate multiple VNF
+
+Multiple Vnf Immediate Empty Schedule Id MultipleVnfImmediateEmptyScheduleId.json.template ${status_code_variable} ${multiple_vnf_template_folder}
+ [Tags] ete failure immediate multiple VNF
+
+Multiple Vnf Immediate Empty Additional Duration MultipleVnfImmediateEmptyAdditionalDuration.json.template ${status_code_variable} ${multiple_vnf_template_folder}
+ [Tags] ete failure immediate multiple VNF
+
+Multiple Vnf Immediate Empty User Id MultipleVnfImmediateEmptyUserId.json.template ${status_code_variable} ${multiple_vnf_template_folder}
+ [Tags] ete failure immediate multiple VNF \ No newline at end of file
diff --git a/cmso-robot/robot/testsuites/ChangeManagementRejection.robot b/cmso-robot/robot/testsuites/ChangeManagementRejection.robot
new file mode 100644
index 0000000..ea63ac8
--- /dev/null
+++ b/cmso-robot/robot/testsuites/ChangeManagementRejection.robot
@@ -0,0 +1,18 @@
+*** Settings ***
+Documentation Creates VID VNF Instance
+
+Library StringTemplater
+Library UUID
+
+Resource ../resources/test_templates/change_management.robot
+
+# Test Setup
+Test Template Change Management Rejection Template
+# Test Teardown
+*** Variable***
+${status_code_variable}= 202
+${template_folder}= robot/assets/templates/changemanagement
+*** Test Cases ***
+Change Management Rejection OneVnfOneChangeWindowReplaceVNFInfra.json.template ${template_folder}
+ [Tags] ete rejection
+
diff --git a/cmso-robot/robot/testsuites/CheckLog.robot b/cmso-robot/robot/testsuites/CheckLog.robot
new file mode 100644
index 0000000..13d7b1c
--- /dev/null
+++ b/cmso-robot/robot/testsuites/CheckLog.robot
@@ -0,0 +1,39 @@
+*** Settings ***
+Documentation Creates VID VNF Instance
+
+Library StringTemplater
+Library UUID
+
+Resource ../resources/test_templates/check_logs.robot
+
+# Test Setup
+# Test Teardown
+*** Variable***
+${user_name}= cr057g
+${password}= cr057g
+${template_folder}= robot/assets/templates/changemanagement
+${fail_template_folder}= robot/assets/templates/FailureCasesChangeManagement
+*** Test Cases ***
+
+Check Audit Logs
+ Check Audit Logs ${user_name} ${password} OneVnfImmediateReplaceVNFInfra.json.template ${template_folder}
+
+Check Debug Logs
+ Check Debug Logs ${user_name} ${password} OneVnfImmediateReplaceVNFInfra.json.template ${template_folder}
+
+Check Metric Logs
+ Check Metric Logs ${user_name} ${password} OneVnfImmediateReplaceVNFInfra.json.template ${template_folder}
+
+Check Error Logs
+ Check Error Logs ${user_name} ${password} OneVnfOneChangeWindowEmptyScheduleID.json.template ${fail_template_folder}
+ [Tags]
+
+
+
+
+
+
+
+
+
+
diff --git a/cmso-robot/robot/testsuites/CheckScheduleStatus.robot b/cmso-robot/robot/testsuites/CheckScheduleStatus.robot
new file mode 100644
index 0000000..2f96ecb
--- /dev/null
+++ b/cmso-robot/robot/testsuites/CheckScheduleStatus.robot
@@ -0,0 +1,18 @@
+*** Settings ***
+Documentation Creates VID VNF Instance
+
+Library StringTemplater
+Library UUID
+
+Resource ../resources/test_templates/change_management.robot
+
+# Test Setup
+# Test Teardown
+*** Variable***
+${template_folder}= robot/assets/templates/changemanagement
+*** Test Cases ***
+Change Management Status Immediate
+ Record Status Immediate Template OneVnfImmediateReplaceVNFInfra.json.template ${template_folder}
+
+Change Management Status
+ Record Status Template OneVnfOneChangeWindowReplaceVNFInfra.json.template ${template_folder} \ No newline at end of file
diff --git a/cmso-robot/robot/testsuites/MiscTests.robot b/cmso-robot/robot/testsuites/MiscTests.robot
new file mode 100644
index 0000000..6873e3f
--- /dev/null
+++ b/cmso-robot/robot/testsuites/MiscTests.robot
@@ -0,0 +1,23 @@
+*** Settings ***
+Documentation Creates VID VNF Instance
+
+Library StringTemplater
+Library UUID
+
+Resource ../resources/test_templates/change_management.robot
+Resource ../resources/test_templates/check_logs.robot
+
+# Test Setup
+# Test Teardown
+*** Variable***
+${user_name}=
+${password}=
+${uuid_list_file}= robot/assets/get_schedule_UUIDs.txt
+${template_folder}= robot/assets/templates/changemanagement
+*** Test Cases ***
+Get Schedule
+ Get Schedule Test Template ${uuid_list_file}
+
+Post Existing Immediate Schedule
+ Change Management Already Exists Immediate Template OneVnfImmediateReplaceVNFInfra.json.template ${template_folder}
+
diff --git a/cmso-robot/robot/testsuites/VtmAccess.robot b/cmso-robot/robot/testsuites/VtmAccess.robot
new file mode 100644
index 0000000..4a9c0aa
--- /dev/null
+++ b/cmso-robot/robot/testsuites/VtmAccess.robot
@@ -0,0 +1,105 @@
+*** Settings ***
+Documentation Creates VID VNF Instance
+
+Library String
+Library OperatingSystem
+Library StringTemplater
+Library Collections
+Library XML
+
+Resource ../resources/scheduler_common.robot
+Resource ../resources/vtm_common.robot
+*** Variables ****
+${AOTS_USER} ${GLOBAL_VID_USERID}
+${ASSETSSTRING} dummy-id
+
+*** Test Cases ***
+Test1
+ ${display} Create List actualStartDate actualEndDate dateModified assetId
+ ${assets}= Create List dummy
+ ${status}= Create List New Assigned Planning Scheduled Pending WorkInProgress Resolved
+ ${filter}= Create Dictionary plannedStartDateFrom=1505389844 assetId=${assets}
+ vTM Query Template vtm display=${display} filter=${filter}
+
+Delete Tickets
+ ${tickets} Create List dummy-id
+ :for ${ticket} in @{tickets}
+ \ vTM Close Ticket vtm ${ticket} ${GLOBAL_VID_USERID}
+
+Delete Old Tickets Atomic
+ @{assets}= Split String ${ASSETS} separator=,
+ ${end_time}= Get Current Date UTC - 1440 minutes result_format=timestamp exclude_millis=False
+ ${end_time}= Convert Date ${end_time} epoch
+ ${end_time}= Evaluate int(${end_time})
+ ${display} Create List actualStartDate actualEndDate dateModified assetId
+ ${status}= Create List New Assigned Planning Scheduled Pending WorkInProgress Resolved
+ ${filter}= Create Dictionary plannedStartDateFrom=0 plannedEndDateTo=${end_time} assetId=@{assets} status=${status}
+ ${resp}= vTM Query Template vtm display=${display} filter=${filter}
+ Log ${resp.json()}
+ ${list}= Get From Dictionary ${resp.json()} changeInfo
+ ${changeIds}= Create Dictionary
+ :for ${ticket} in @{list}
+ \ ${changeId}= Get From Dictionary ${ticket} changeId
+ \ Set To Dictionary ${changeIds} ${changeId}=1
+ # Weed out dupes if any
+ ${idlist} Get Dictionary Keys ${changeIds}
+ :for ${changeId} in @{idlist}
+ \ vTM Close Ticket vtm ${changeId} ${AOTS_USER}
+
+Delete Old Scheduler Tickets
+ :for ${env} in @{DELETE_TICKET_ENVS}
+ \ Set Global Variable ${GLOBAL_SCHEDULER_HOST} ${env['scheduler']}
+ \ Set Global Variable ${GLOBAL_VTM_HOST} ${env['vtm']}
+ \ Delete Scheduler Tickets For ENV
+
+
+Cancel Tickets
+ ${tickets} Create List dummy-id
+ :for ${ticket} in @{tickets}
+ \ vTM Cancel Ticket vtm ${ticket}
+
+
+Delete Schedule
+ ${uuid}= Catenate dummy-id
+ ${resp}= Delete Change Management auth schedules/${uuid}
+
+
+*** Keywords ***
+Delete Scheduler Tickets For ENV
+ # Make sure that the Scheduler in the config and the vTM system are the same.
+ # We will match the tickets to be deleted to the tickets in the scheduler DB
+ # to ensure we don't clobber other folks test data!
+ ${scheduler_tickets}= Get Scheduler Tickets
+ # ELiminate dupes
+ @{assets} Get Dictionary Values ${scheduler_tickets}
+ @{assets}= Remove Duplicates ${assets}
+ ${end_time}= Get Current Date UTC - 1440 minutes result_format=timestamp exclude_millis=False
+ ${end_time}= Convert Date ${end_time} epoch
+ ${end_time}= Evaluate int(${end_time})
+ ${display} Create List actualStartDate actualEndDate dateModified assetId requesterId
+ ${status}= Create List New Assigned Planning Scheduled Pending WorkInProgress Resolved
+ ${filter}= Create Dictionary plannedStartDateFrom=0 plannedEndDateTo=${end_time} assetId=@{assets} status=${status}
+ ${resp}= vTM Query Template vtm display=${display} filter=${filter}
+ Log ${resp.json()}
+ ${list}= Get From Dictionary ${resp.json()} changeInfo
+
+ ## Get list of tickets that are both in our DB and in AOTS
+ ${changeIds}= Create Dictionary
+ :for ${ticket} in @{list}
+ \ ${changeId}= Get From Dictionary ${ticket} changeId
+ \ ${status} ${value}= Run Keyword and Ignore Error Get From Dictionary ${scheduler_tickets} ${changeId}
+ \ Run Keyword If '${status}'=='PASS' Set To Dictionary ${changeIds} ${changeId}=1
+ # Weed out dupes if any and only cance ones in our DB!
+ ${idlist} Get Dictionary Keys ${changeIds}
+ :for ${changeId} in @{idlist}
+ \ vTM Cancel Ticket vtm ${changeId}
+
+Get Scheduler Tickets
+ ${resp}= Get Change Management auth schedules/scheduleDetails
+ ${dict}= Create Dictionary
+ Log ${resp.json()}
+ :for ${details} in @{resp.json()}
+ \ ${status} ${value}= Run Keyword and Ignore Error Get From Dictionary ${details} aotsChangeId
+ \ ${assetId}= Get From Dictionary ${details} vnfName
+ \ Run Keyword If '${status}'=='PASS' Set To Dictionary ${dict} ${value}=${assetId}
+ [Return] ${dict}
diff --git a/cmso-robot/runVtmCleanup.sh b/cmso-robot/runVtmCleanup.sh
new file mode 100644
index 0000000..00398ae
--- /dev/null
+++ b/cmso-robot/runVtmCleanup.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+#
+ROBOT_CMD="python -m robot.run"
+ROBOT_HOME=`pwd`
+ROBOT_PATH=${ROBOT_PATH}:${ROBOT_HOME}/robot/library
+ROBOT_PATH=${ROBOT_PATH}:${ROBOT_HOME}/robot/locallibrary/cmsoUtils
+VARIABLE_FILES="${VARIABLE_FILES} -V ${ROBOT_HOME}/robot/assets/test_properties.py"
+
+${ROBOT_CMD} ${OUTPUT} -P ${ROBOT_PATH} ${VARIABLE_FILES} ${VARIABLES} -s SchedulerRobot.Robot.Testsuites.VtmAccess -t "SchedulerRobot.Robot.Testsuites.VtmAccess.delete old scheduler tickets" ${ROBOT_HOME}
+
diff --git a/cmso-robot/setup.sh b/cmso-robot/setup.sh
new file mode 100644
index 0000000..1cbd3f9
--- /dev/null
+++ b/cmso-robot/setup.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+#
+# setup : script to setup required runtime environment. This script can be run again to update anything
+# this should stay in your project directory
+#
+
+# get the path
+path=$(pwd)
+pip install --upgrade pip
+pip install --no-cache-dir --target="$path/robot/library" 'selenium<=3.0.0'
+pip install --no-cache-dir --target="$path/robot/library" 'requests==2.11.1'
+pip install --no-cache-dir --target="$path/robot/library" 'robotframework-selenium2library==1.8.0'
+pip install --no-cache-dir --target="$path/robot/library" 'robotframework-databaselibrary==0.8.1'
+pip install --no-cache-dir --target="$path/robot/library" 'robotframework-extendedselenium2library==0.9.1'
+pip install --no-cache-dir --target="$path/robot/library" 'robotframework-requests==0.4.5'
+pip install --no-cache-dir --target="$path/robot/library" 'robotframework-sshlibrary==2.1.2'
+pip install --no-cache-dir --target="$path/robot/library" 'robotframework-sudslibrary==0.8'
+pip install --no-cache-dir --target="$path/robot/library" 'robotframework-ftplibrary==1.3'
+pip install --no-cache-dir --target="$path/robot/library" 'robotframework-rammbock==0.4.0.1'
+pip install --no-cache-dir --target="$path/robot/library" 'deepdiff==2.5.1'
+pip install --no-cache-dir --target="$path/robot/library" 'dnspython==1.15.0'
+pip install --no-cache-dir --target="$path/robot/library" 'robotframework-httplibrary==0.4.2'
+pip install --no-cache-dir --target="$path/robot/library" 'robotframework-archivelibrary==0.3.2'
+pip install --no-cache-dir --target="$path/robot/library" 'PyYAML==3.12'
+
+# NOTE: Patch to incude explicit install of paramiko to 2.0.2 to work with sshlibrary 2.1.2
+# This should be removed on new release of paramiko (2.1.2) or sshlibrary
+# https://github.com/robotframework/SSHLibrary/issues/157
+pip install --no-cache-dir --target="$path/robot/library" -U 'paramiko==2.0.2'
+
+#
+# Get the appropriate chromedriver. Default to linux64
+#
+CHROMEDRIVER_URL=http://chromedriver.storage.googleapis.com/2.29
+CHROMEDRIVER_ZIP=chromedriver_linux64.zip
+
+# Handle mac and windows
+OS=`uname -s`
+case $OS in
+ MINGW*_NT*)
+ CHROMEDRIVER_ZIP=chromedriver_win32.zip
+ ;;
+ Darwin*)
+ CHROMEDRIVER_ZIP=chromedriver_mac64.zip
+ ;;
+ *) echo "Defaulting to Linux 64" ;;
+esac
+
+
+# Temporar remove until we figure out proxy blocking issue
+# wget -O chromedriver.zip $CHROMEDRIVER_URL/$CHROMEDRIVER_ZIP
+# unzip chromedriver.zip -d /usr/local/bin
+
+if [ $CHROMEDRIVER_ZIP == 'chromedriver_linux64.zip' ]
+then
+ echo Skipping
+else
+ curl $CHROMEDRIVER_URL/$CHROMEDRIVER_ZIP -o chromedriver.zip
+ unzip chromedriver.zip
+fi