Change Management Schedule Optimization

Adding scripts and robot test suites for cmso as per CSIT procedure
Fixing the start up scripts to use docker
Removing .pyc files
Fix copyright headers for the shell scripts

Change-Id: I61492abd5d5060b5a773dec74320f2ecfc0fcbf5
Issue-ID: OPTFRA-382
Signed-off-by: sv764t <sv764t@att.com>
Signed-off-by: vrvarma <vv8305@att.com>
diff --git a/tests/optf-cmso/cmso/attlibs/CurlLibrary.py b/tests/optf-cmso/cmso/attlibs/CurlLibrary.py
new file mode 100644
index 0000000..44c6229
--- /dev/null
+++ b/tests/optf-cmso/cmso/attlibs/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/tests/optf-cmso/cmso/attlibs/HTTPUtils.py b/tests/optf-cmso/cmso/attlibs/HTTPUtils.py
new file mode 100644
index 0000000..f9d380c
--- /dev/null
+++ b/tests/optf-cmso/cmso/attlibs/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/tests/optf-cmso/cmso/attlibs/JSONUtils.py b/tests/optf-cmso/cmso/attlibs/JSONUtils.py
new file mode 100644
index 0000000..5df1e5c
--- /dev/null
+++ b/tests/optf-cmso/cmso/attlibs/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/tests/optf-cmso/cmso/attlibs/OSUtils.py b/tests/optf-cmso/cmso/attlibs/OSUtils.py
new file mode 100644
index 0000000..78968f0
--- /dev/null
+++ b/tests/optf-cmso/cmso/attlibs/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/tests/optf-cmso/cmso/attlibs/RequestsClientCert.py b/tests/optf-cmso/cmso/attlibs/RequestsClientCert.py
new file mode 100644
index 0000000..e1fd66f
--- /dev/null
+++ b/tests/optf-cmso/cmso/attlibs/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/tests/optf-cmso/cmso/attlibs/StringTemplater.py b/tests/optf-cmso/cmso/attlibs/StringTemplater.py
new file mode 100644
index 0000000..680600f
--- /dev/null
+++ b/tests/optf-cmso/cmso/attlibs/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/tests/optf-cmso/cmso/attlibs/UID.py b/tests/optf-cmso/cmso/attlibs/UID.py
new file mode 100644
index 0000000..4374809
--- /dev/null
+++ b/tests/optf-cmso/cmso/attlibs/UID.py
@@ -0,0 +1,8 @@
+import uuid
+
+class UID:
+    """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/tests/optf-cmso/cmso/resources/approval_requests.robot b/tests/optf-cmso/cmso/resources/approval_requests.robot
new file mode 100644
index 0000000..9de1887
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/approval_requests.robot
@@ -0,0 +1,38 @@
+*** Settings ***
+Documentation	  Scheduler keywords
+
+#Library   StringTemplater
+#Library   UUID
+Library		../attlibs/UID.py
+Library		../attlibs/StringTemplater.py
+Library   DateTime
+Library   Collections
+
+Resource	scheduler_common.robot
+Resource	json_templater.robot
+
+*** Variables ****
+${TEMPLATES}    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}
+    
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyDomain.json.template b/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyDomain.json.template
new file mode 100644
index 0000000..1aea5ef
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : "SNIRO.TimeLimitAndVerticalTopology",
+		"vnfDetails" : [{
+				"groupId" : "",
+				"node" : [
+					"ZRDM1MMSC04${testid}"
+				],
+				"changeWindow" : [{
+						"startTime" : "${start_time1}",
+						"endTime" : "${end_time1}"
+					}
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyScheduleID.json.template b/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyScheduleID.json.template
new file mode 100644
index 0000000..2733b07
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : "SNIRO.TimeLimitAndVerticalTopology",
+		"vnfDetails" : [{
+				"groupId" : "",
+				"node" : [
+					"ZRDM1MMSC04${testid}"
+				],
+				"changeWindow" : [{
+						"startTime" : "${start_time1}",
+						"endTime" : "${end_time1}"
+					}
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyScheduleName.json.template b/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyScheduleName.json.template
new file mode 100644
index 0000000..9d827bd
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : "SNIRO.TimeLimitAndVerticalTopology",
+		"vnfDetails" : [{
+				"groupId" : "",
+				"node" : [
+					"ZRDM1MMSC04${testid}"
+				],
+				"changeWindow" : [{
+						"startTime" : "${start_time1}",
+						"endTime" : "${end_time1}"
+					}
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyUserID.json.template b/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowEmptyUserID.json.template
new file mode 100644
index 0000000..d779f2c
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : "SNIRO.TimeLimitAndVerticalTopology",
+		"vnfDetails" : [{
+				"groupId" : "",
+				"node" : [
+					"ZRDM1MMSC04${testid}"
+				],
+				"changeWindow" : [{
+						"startTime" : "${start_time1}",
+						"endTime" : "${end_time1}"
+					}
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowIncorrectPolicyId.json.template b/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowIncorrectPolicyId.json.template
new file mode 100644
index 0000000..061b6b7
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : [
+					"ZRDM1MMSC04${testid}"
+				],
+				"changeWindow" : [{
+						"startTime" : "${start_time1}",
+						"endTime" : "${end_time1}"
+					}
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowIncorrectWorkflow.json.template b/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowIncorrectWorkflow.json.template
new file mode 100644
index 0000000..87ab8f3
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : "SNIRO.TimeLimitAndVerticalTopology",
+		"vnfDetails" : [{
+				"groupId" : "",
+				"node" : [
+					"ZRDM1MMSC04${testid}"
+				],
+				"changeWindow" : [{
+						"startTime" : "${start_time1}",
+						"endTime" : "${end_time1}"
+					}
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNegativeNormalDurationInSeconds.json.template b/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNegativeNormalDurationInSeconds.json.template
new file mode 100644
index 0000000..633ce46
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : "SNIRO.TimeLimitAndVerticalTopology",
+		"vnfDetails" : [{
+				"groupId" : "",
+				"node" : [
+					"ZRDM1MMSC04${testid}"
+				],
+				"changeWindow" : [{
+						"startTime" : "${start_time1}",
+						"endTime" : "${end_time1}"
+					}
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNoEndTime.json.template b/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNoEndTime.json.template
new file mode 100644
index 0000000..62dae5b
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : "SNIRO.TimeLimitAndVerticalTopology",
+		"vnfDetails" : [{
+				"groupId" : "",
+				"node" : [
+					"ZRDM1MMSC04${testid}"
+				],
+				"changeWindow" : [{
+						"startTime" : "${start_time1}",
+						"endTime" : ""
+					}
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNoNodeName.json.template b/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNoNodeName.json.template
new file mode 100644
index 0000000..22fc89a
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : "SNIRO.TimeLimitAndVerticalTopology",
+		"vnfDetails" : [{
+				"groupId" : "",
+				"node" : [
+					""
+				],
+				"changeWindow" : [{
+						"startTime" : "${start_time1}",
+						"endTime" : "${end_time1}"
+					}
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNoStartTime.json.template b/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowNoStartTime.json.template
new file mode 100644
index 0000000..4f1f25b
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : "SNIRO.TimeLimitAndVerticalTopology",
+		"vnfDetails" : [{
+				"groupId" : "",
+				"node" : [
+					"ZRDM1MMSC04${testid}"
+				],
+				"changeWindow" : [{
+						"startTime" : "",
+						"endTime" : "${end_time1}"
+					}
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowSwitchedTime.json.template b/tests/optf-cmso/cmso/resources/assets/templates/FailureCasesChangeManagement/OneVnfOneChangeWindowSwitchedTime.json.template
new file mode 100644
index 0000000..a7f19d4
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : "SNIRO.TimeLimitAndVerticalTopology",
+		"vnfDetails" : [{
+				"groupId" : "",
+				"node" : [
+					"ZRDM1MMSC04${testid}"
+				],
+				"changeWindow" : [{
+						"startTime" : "${end_time1}",
+						"endTime" : "${start_time1}"
+					}
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyAdditionalDuration.json.template b/tests/optf-cmso/cmso/resources/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyAdditionalDuration.json.template
new file mode 100644
index 0000000..5c9e0a3
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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/tests/optf-cmso/cmso/resources/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyDomain.json.template b/tests/optf-cmso/cmso/resources/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyDomain.json.template
new file mode 100644
index 0000000..19c1d87
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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/tests/optf-cmso/cmso/resources/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyScheduleId.json.template b/tests/optf-cmso/cmso/resources/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyScheduleId.json.template
new file mode 100644
index 0000000..ab92d18
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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/tests/optf-cmso/cmso/resources/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyUserId.json.template b/tests/optf-cmso/cmso/resources/assets/templates/MutipleVNFImmediateFailureCases/MultipleVnfImmediateEmptyUserId.json.template
new file mode 100644
index 0000000..9de749c
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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/tests/optf-cmso/cmso/resources/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyDomain.json.template b/tests/optf-cmso/cmso/resources/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyDomain.json.template
new file mode 100644
index 0000000..8d2f09f
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : [
+					"ZRDM1MMSC04${testid}"
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyScheduleId.json.template b/tests/optf-cmso/cmso/resources/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyScheduleId.json.template
new file mode 100644
index 0000000..b363a27
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : [
+					"ZRDM1MMSC04${testid}"
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyScheduleName.json.template b/tests/optf-cmso/cmso/resources/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyScheduleName.json.template
new file mode 100644
index 0000000..4bb70ec
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : [
+					"ZRDM1MMSC04${testid}"
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptySchedulingInfo.json.template b/tests/optf-cmso/cmso/resources/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptySchedulingInfo.json.template
new file mode 100644
index 0000000..461f166
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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/tests/optf-cmso/cmso/resources/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyUserId.json.template b/tests/optf-cmso/cmso/resources/assets/templates/OneVNFImmediateFailureCases/OneVnfImmediateEmptyUserId.json.template
new file mode 100644
index 0000000..a2a4ba4
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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/tests/optf-cmso/cmso/resources/assets/templates/SearchSchedulerDetails/OneVnfImmediate_domainData1.json.template b/tests/optf-cmso/cmso/resources/assets/templates/SearchSchedulerDetails/OneVnfImmediate_domainData1.json.template
new file mode 100644
index 0000000..73c2e34
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/assets/templates/SearchSchedulerDetails/OneVnfImmediate_domainData1.json.template
@@ -0,0 +1,26 @@
+{
+	"domain" : "ChangeManagement",
+	"scheduleId" : "${uuid}",
+	"scheduleName" : "${uuid}",
+	"userId" : "${userId}",
+	"domainData" : [{
+			"CallbackUrl" : "${callbackUrl}",
+			"CallbackData" : "${callbackData}",
+			"WorkflowName" : "${workflow}",
+			"plans" : "Run ${workflow}",
+			"question.000000000000001" : "Yes",
+			"domainName1" : "domainValue1"
+		}
+	],
+	"schedulingInfo" : {
+		"normalDurationInSeconds" : 100,
+		"additionalDurationInSeconds" : 10,
+		"vnfDetails" : [{
+				"groupId" : "group1",
+				"node" : [
+					"${node1}"
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/SearchSchedulerDetails/OneVnfImmediate_domainData2.json.template b/tests/optf-cmso/cmso/resources/assets/templates/SearchSchedulerDetails/OneVnfImmediate_domainData2.json.template
new file mode 100644
index 0000000..0f02116
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/assets/templates/SearchSchedulerDetails/OneVnfImmediate_domainData2.json.template
@@ -0,0 +1,27 @@
+{
+	"domain" : "ChangeManagement",
+	"scheduleId" : "${uuid}",
+	"scheduleName" : "${uuid}",
+	"userId" : "${userId}",
+	"domainData" : [{
+			"CallbackUrl" : "${callbackUrl}",
+			"CallbackData" : "${callbackData}",
+			"WorkflowName" : "${workflow}",
+			"plans" : "Run ${workflow}",
+			"question.000000000000001" : "Yes",
+			"domainName1" : "domainValue1",
+			"domainName2" : "domainValue2"
+		}
+	],
+	"schedulingInfo" : {
+		"normalDurationInSeconds" : 100,
+		"additionalDurationInSeconds" : 10,
+		"vnfDetails" : [{
+				"groupId" : "group1",
+				"node" : [
+					"${node1}"
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/SearchSchedulerDetails/OneVnfImmediate_domainData3.json.template b/tests/optf-cmso/cmso/resources/assets/templates/SearchSchedulerDetails/OneVnfImmediate_domainData3.json.template
new file mode 100644
index 0000000..dc64483
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/assets/templates/SearchSchedulerDetails/OneVnfImmediate_domainData3.json.template
@@ -0,0 +1,29 @@
+{
+	"domain" : "ChangeManagement",
+	"scheduleId" : "${uuid}",
+	"scheduleName" : "${uuid}",
+	"userId" : "${userId}",
+	"domainData" : [{
+			"CallbackUrl" : "${callbackUrl}",
+			"CallbackData" : "${callbackData}",
+			"WorkflowName" : "${workflow}",
+			"plans" : "Run ${workflow}",
+			"question.000000000000001" : "Yes",
+			"domainName1" : "domainValue1",
+			"domainName2" : "domainValue2",
+			"domainName3" : "domainValue3"
+			
+		}
+	],
+	"schedulingInfo" : {
+		"normalDurationInSeconds" : 100,
+		"additionalDurationInSeconds" : 10,
+		"vnfDetails" : [{
+				"groupId" : "group1",
+				"node" : [
+					"${node1}"
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/MultipleVnfImmediate.json.template b/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/MultipleVnfImmediate.json.template
new file mode 100644
index 0000000..542e19e
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/OneGroupMultipleVNFsOneChangeWindow.json.template b/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/OneGroupMultipleVNFsOneChangeWindow.json.template
new file mode 100644
index 0000000..9bfd3d2
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : "SNIRO_CM.TimeLimitAndVerticalTopology_pserver",
+		"vnfDetails" : [{
+				"groupId" : "group",
+				"node" : [
+					"${node1}",
+					"${node2}",
+					"${node3}"
+				],
+				"changeWindow" : [{
+						"startTime" : "${start_time1}",
+						"endTime" : "${end_time1}"
+					}
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/OneGroupMultipleVNSsTwoChangeWindows.json.template b/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/OneGroupMultipleVNSsTwoChangeWindows.json.template
new file mode 100644
index 0000000..a3cef8a
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : "SNIRO_CM.TimeLimitAndVerticalTopology_pserver",
+		"vnfDetails" : [{
+				"groupId" : "Group1",
+				"node" : [
+					"${node1}",
+					"${node2}",
+					"${node3}",
+					"${node4}"
+				],
+				"changeWindow" : [{
+						"startTime" : "${start_time1}",
+						"endTime" : "${end_time1}"
+					},{
+						"startTime" : "${start_time2}",
+						"endTime" : "${end_time2}"
+					}
+				]
+			}
+		]
+	}
+}
+
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/OneVnfImmediate.json.template b/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/OneVnfImmediate.json.template
new file mode 100644
index 0000000..c108c15
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/OneVnfImmediateIncorrectWorkflow.json.template b/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/OneVnfImmediateIncorrectWorkflow.json.template
new file mode 100644
index 0000000..e91c653
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/OneVnfImmediateReplaceVNFInfra.json.template b/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/OneVnfImmediateReplaceVNFInfra.json.template
new file mode 100644
index 0000000..d896a62
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/OneVnfOneChangeWindow.json.template b/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/OneVnfOneChangeWindow.json.template
new file mode 100644
index 0000000..93bb2ac
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : "SNIRO_CM.TimeLimitAndVerticalTopology_pserver",
+		"vnfDetails" : [{
+				"groupId" : "group",
+				"node" : [
+					"${node1}"
+				],
+				"changeWindow" : [{
+						"startTime" : "${start_time1}",
+						"endTime" : "${end_time1}"
+					}
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/OneVnfOneChangeWindowEmptyCallbackData.json.template b/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/OneVnfOneChangeWindowEmptyCallbackData.json.template
new file mode 100644
index 0000000..e6e584b
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : "SNIRO_CM.TimeLimitAndVerticalTopology_v2_split_1",
+		"vnfDetails" : [{
+				"groupId" : "group",
+				"node" : [
+					"${node1}"
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/OneVnfOneChangeWindowEmptyCallbackURL.json.template b/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/OneVnfOneChangeWindowEmptyCallbackURL.json.template
new file mode 100644
index 0000000..57634d6
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : "SNIRO_CM.TimeLimitAndVerticalTopology_v2_split_1",
+		"vnfDetails" : [{
+				"groupId" : "group",
+				"node" : [
+					"${node1}"
+				],
+				"changeWindow" : [{
+						"startTime" : "${start_time1}",
+						"endTime" : "${end_time1}"
+					}
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/OneVnfOneChangeWindowReplaceVNFInfra.json.template b/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/OneVnfOneChangeWindowReplaceVNFInfra.json.template
new file mode 100644
index 0000000..e5d62bf
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/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" : "SNIRO_CM.TimeLimitAndVerticalTopology_v2_split_1",
+		"vnfDetails" : [{
+				"groupId" : "group",
+				"node" : [
+					"${node1}"
+				],
+				"changeWindow" : [{
+						"startTime" : "${start_time1}",
+						"endTime" : "${end_time1}"
+					}
+				]
+			}
+		]
+	}
+}
diff --git a/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/VidCallbackData.json.template b/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/VidCallbackData.json.template
new file mode 100644
index 0000000..177b55a
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/assets/templates/changemanagement/VidCallbackData.json.template
@@ -0,0 +1,40 @@
+{
+	"requestType" : "Update",
+	"requestDetails" : [{
+			"vnfName" : "mdns_2017_1011_oh22u_20171103",
+			"vnfInstanceId" : "b8d99523-1e83-4fd1-b42f-849361ef7024",
+			"modelInfo" : {
+				"modelType" : "vnf",
+				"modelInvariantId" : "93e16072-715a-42ef-9d0a-080052d6b716",
+				"modelVersionId" : "4ec07a2d-6bb5-4373-8ed6-4bc7ac1246fd",
+				"modelName" : "mdns_2017_1011_oh22u_20171103",
+				"modelCustomizationId" : "1779a999-ea17-4f31-98e9-75b6fbdd0acb"
+			},
+			"cloudConfiguration" : {
+				"lcpCloudRegionId" : "mdt1",
+				"tenantId" : "88a6ca3ee0394ade9403f075db23167e"
+			},
+			"requestInfo" : {
+				"source" : "VID",
+				"suppressRollback" : false,
+				"requestorId" : "az2016"
+			},
+			"relatedInstanceList" : [{
+					"relatedInstance" : {
+						"instanceId" : "54ba3628-9ee5-4b32-8a2a-3abf001bed4e",
+						"modelInfo" : {
+							"modelType" : "service",
+							"modelInvariantId" : "e58733ef-43cb-4b6b-b641-922078b6c88b",
+							"modelVersionId" : "4ec07a2d-6bb5-4373-8ed6-4bc7ac1246fd",
+							"modelName" : "mdns_2017_1011",
+							"modelVersion" : "4.0"
+						}
+					}
+				}
+			],
+			"requestParameters" : {
+				"usePreload" : true
+			}
+		}
+	]
+}
diff --git a/tests/optf-cmso/cmso/resources/browser_setup.robot b/tests/optf-cmso/cmso/resources/browser_setup.robot
new file mode 100644
index 0000000..032759e
--- /dev/null
+++ b/tests/optf-cmso/cmso/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/tests/optf-cmso/cmso/resources/change_management_ete.robot b/tests/optf-cmso/cmso/resources/change_management_ete.robot
new file mode 100644
index 0000000..2b1ff54
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/change_management_ete.robot
@@ -0,0 +1,103 @@
+*** Settings ***
+Documentation	  Creates VID VNF Instance
+
+#Library   StringTemplater
+#Library   UUID
+Library		../attlibs/UID.py
+Library		../attlibs/StringTemplater.py
+Library   Collections
+Library   SSHLibrary
+
+Resource	scheduler_common.robot
+Resource	json_templater.robot
+Resource	create_schedule.robot
+Resource	approval_requests.robot
+
+*** Variables ****
+${TEMPLATES}	/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
+    
+    
+    
+Change Management Immediate Template Query Data    
+   [Arguments]    ${request_file}    ${workflow}  
+   ${template_folder}=    Catenate   ${TEMPLATES}/SearchSchedulerDetails
+   ${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}
+   [Return]    ${uuid}
+   
+   
+
+ 
+	        
diff --git a/tests/optf-cmso/cmso/resources/create_schedule.robot b/tests/optf-cmso/cmso/resources/create_schedule.robot
new file mode 100644
index 0000000..43d5ff1
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/create_schedule.robot
@@ -0,0 +1,54 @@
+*** Settings ***
+Documentation	  SCheduler tests
+
+#Library   StringTemplater
+#Library   UUID
+Library		../attlibs/UID.py
+Library		../attlibs/StringTemplater.py
+Library		../attlibs/JSONUtils.py
+Library   String
+Library   DateTime
+Library   Collections 
+Library   OperatingSystem 
+#Library   JSONUtils
+
+Resource	scheduler_common.robot
+Resource	json_templater.robot
+
+*** Variables ****
+${VID_TEMPLATES}    /assets/templates/changemanagement
+${GLOBAL_VID_CALLBACK_URL}		http://127.0.0.1:8080/scheduler/v1/loopbacktest/vid
+${GLOBAL_VID_USERID}		jf9860
+${NODES}	aaiaic25ctsf0002v,dpa2bhsfe0001v,ctsf0008v,nsbg0002v
+${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    ${CURDIR}${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    ${CURDIR}${TEMPLATES}/${request_file}   ${map}    
+    ${resp}=   Post Change Management   auth   schedules/${uuid}   data=${data}
+    [Return]   ${resp}
+    
+       
+    
diff --git a/tests/optf-cmso/cmso/resources/files.robot b/tests/optf-cmso/cmso/resources/files.robot
new file mode 100644
index 0000000..fcfffbb
--- /dev/null
+++ b/tests/optf-cmso/cmso/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/tests/optf-cmso/cmso/resources/json_templater.robot b/tests/optf-cmso/cmso/resources/json_templater.robot
new file mode 100644
index 0000000..ebbbf43
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/json_templater.robot
@@ -0,0 +1,21 @@
+*** Settings ***
+Documentation     This resource is filling out json string templates and returning the json back
+Library 	      RequestsLibrary
+#Library           StringTemplater
+Library		../attlibs/StringTemplater.py
+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}
diff --git a/tests/optf-cmso/cmso/resources/misc.robot b/tests/optf-cmso/cmso/resources/misc.robot
new file mode 100644
index 0000000..e20640c
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/misc.robot
@@ -0,0 +1,43 @@
+*** Settings ***
+Library     Collections
+Library     String
+#Library     UUID
+Library		../attlibs/UID.py
+Library     Process
+Library     HttpLibrary.HTTP
+Documentation     Miscellaneous keywords
+
+Resource    json_templater.robot
+Resource    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}
+    
+    
diff --git a/tests/optf-cmso/cmso/resources/scheduler_common.robot b/tests/optf-cmso/cmso/resources/scheduler_common.robot
new file mode 100644
index 0000000..dd2f611
--- /dev/null
+++ b/tests/optf-cmso/cmso/resources/scheduler_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		../attlibs/UID.py
+#Library           HTTPUtils
+Library		../attlibs/HTTPUtils.py
+Library           String
+Resource   misc.robot
+*** Variables ***
+*** Variables ***
+${GLOBAL_SCHEDULER_PORT}		8080
+${GLOBAL_SCHEDULER_PROTOCOL}		http
+#${GLOBAL_SCHEDULER_HOST}		127.0.0.1
+${GLOBAL_SCHEDULER_USER}		jf9860@csp.att.com
+${GLOBAL_SCHEDULER_PASSWORD}		45=Forty5
+${GLOBAL_APPLICATION_ID}		schedulertest
+${SCHEDULER_PATH}    /cmso/v1
+${CHANGE_MANAGEMENT_PATH}    ${SCHEDULER_PATH}
+${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/tests/optf-cmso/cmso/resources/vtm_common.robot b/tests/optf-cmso/cmso/resources/vtm_common.robot
new file mode 100644
index 0000000..3d5b50a
--- /dev/null
+++ b/tests/optf-cmso/cmso/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		../attlibs/UID.py
+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/tests/optf-cmso/cmso/testsuites/ChangeManagementImmediate.robot b/tests/optf-cmso/cmso/testsuites/ChangeManagementImmediate.robot
new file mode 100644
index 0000000..ee6f8b1
--- /dev/null
+++ b/tests/optf-cmso/cmso/testsuites/ChangeManagementImmediate.robot
@@ -0,0 +1,28 @@
+*** Settings ***
+Documentation	  Creates VID VNF Instance
+
+#Library   StringTemplater
+#Library   UUID
+Library		../attlibs/UID.py
+Library		../attlibs/StringTemplater.py
+Resource    ../resources/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/tests/optf-cmso/cmso/testsuites/__init__.robot b/tests/optf-cmso/cmso/testsuites/__init__.robot
new file mode 100644
index 0000000..baa56c7
--- /dev/null
+++ b/tests/optf-cmso/cmso/testsuites/__init__.robot
@@ -0,0 +1,4 @@
+*** Settings ***
+Documentation    Scheduler 
+
+*** Variables ***