You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stratos.apache.org by ch...@apache.org on 2014/05/14 20:29:48 UTC

[1/4] git commit: added integration test suite

Repository: incubator-stratos
Updated Branches:
  refs/heads/master 160a6e460 -> 0f6cfd3fa


added integration test suite


Project: http://git-wip-us.apache.org/repos/asf/incubator-stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-stratos/commit/cb3a22e8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-stratos/tree/cb3a22e8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-stratos/diff/cb3a22e8

Branch: refs/heads/master
Commit: cb3a22e8c0a07027e6a90dd6923cce08122a7c15
Parents: 6892d21
Author: Chris Snow <ch...@gmail.com>
Authored: Sun May 11 05:48:50 2014 +0000
Committer: Chris Snow <ch...@gmail.com>
Committed: Sun May 11 05:48:50 2014 +0000

----------------------------------------------------------------------
 components/org.apache.stratos.cli/README.md     |   7 +
 components/org.apache.stratos.cli/pom.xml       | 118 ++++++++++-
 .../src/test/python/.gitignore                  |  20 ++
 .../src/test/python/__files/body_cookie.json    |   1 +
 .../test/python/__files/body_tenant_create.json |   1 +
 .../python/__files/body_tenant_deactivate.json  |   1 +
 .../test/python/__files/body_tenant_list.json   |   1 +
 .../src/test/python/__init__.py                 |  19 ++
 .../src/test/python/mappings/cookie.json        |  18 ++
 .../src/test/python/mappings/tenant-create.json |  19 ++
 .../test/python/mappings/tenant-deactivate.json |  16 ++
 .../src/test/python/mappings/tenant-list.json   |  16 ++
 .../src/test/python/test_common.py              |  99 ++++++++++
 .../src/test/python/test_interactive.py         | 195 +++++++++++++++++++
 .../src/test/python/test_noninteractive.py      |  87 +++++++++
 .../src/test/python/wiremock.py                 | 106 ++++++++++
 16 files changed, 723 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cb3a22e8/components/org.apache.stratos.cli/README.md
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/README.md b/components/org.apache.stratos.cli/README.md
new file mode 100644
index 0000000..f03d1b3
--- /dev/null
+++ b/components/org.apache.stratos.cli/README.md
@@ -0,0 +1,7 @@
+### CLI Integration Tests
+
+Run CLI integration tests with:
+
+```mvn -P cli-test integration-test```
+
+You will need python ane pexpect installed.

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cb3a22e8/components/org.apache.stratos.cli/pom.xml
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/pom.xml b/components/org.apache.stratos.cli/pom.xml
index 18d01d2..62b9e97 100644
--- a/components/org.apache.stratos.cli/pom.xml
+++ b/components/org.apache.stratos.cli/pom.xml
@@ -34,6 +34,7 @@
 	
 	<properties>
 		<slf4j.version>1.7.6</slf4j.version>
+		<wiremock.version>1.46</wiremock.version>
 	</properties>
 
 	<dependencies>
@@ -119,7 +120,7 @@
 					<descriptors>
 						<descriptor>src/main/assembly/src.xml</descriptor>
 					</descriptors>
-                    <appendAssemblyId>false</appendAssemblyId>
+					<appendAssemblyId>false</appendAssemblyId>
 				</configuration>
 				<executions>
 					<execution>
@@ -131,7 +132,122 @@
 					</execution>
 				</executions>
 			</plugin>
+			<plugin>  
+				<groupId>org.apache.maven.plugins</groupId> 
+				<artifactId>maven-dependency-plugin</artifactId> 
+				<version>2.7</version> 
+				<executions>
+					<execution> 
+						<id>copy</id> 
+						<phase>pre-integration-test</phase>
+						<goals> 
+							<goal>copy</goal>
+						</goals> 
+						<configuration> 
+							<artifactItems>
+								<!-- Copy the CLI --> 
+								<artifactItem> 
+									<groupId>${project.groupId}</groupId> 
+									<artifactId>${project.artifactId}</artifactId> 
+									<version>${project.version}</version> 
+									<type>jar</type> 
+									<overWrite>true</overWrite> 
+									<outputDirectory>${maven.output.build.path}</outputDirectory> 
+								</artifactItem> 
+							</artifactItems> 
+							<artifactItems> 
+								<artifactItem> 
+									<groupId>com.github.tomakehurst</groupId> 
+									<artifactId>wiremock</artifactId> 
+									<version>${wiremock.version}</version> 
+									<classifier>standalone</classifier> 
+									<type>jar</type> 
+									<overWrite>true</overWrite> 
+									<outputDirectory>${maven.output.build.path}</outputDirectory> 
+								</artifactItem> 
+							</artifactItems> 
+						</configuration> 
+					</execution> 
+				</executions> 
+			</plugin> 
 		</plugins>
 	</build>
 
+	<profiles>
+		<!-- Integration testing the CLI -->
+		<profile>
+			<id>cli-test</id>
+			<build>
+				<plugins>
+					<plugin>
+						<groupId>org.codehaus.mojo</groupId>
+						<artifactId>exec-maven-plugin</artifactId>
+						<version>1.3</version>
+						<executions>
+							<execution>
+								<configuration>
+									<executable>python</executable>
+									<workingDirectory>src/test/python</workingDirectory>
+									<!-- tests common to both interactive and non-interactive use cases -->
+									<arguments>
+										<argument>test_common.py</argument>
+									</arguments>
+									<environmentVariables>
+										<PYTHONPATH>../../main/python:$PYTHONPATH</PYTHONPATH>
+										<CLI_JAR>${project.build.directory}/${project.build.finalName}.jar</CLI_JAR>
+										<WIREMOCK_JAR>${project.build.directory}/dependency/wiremock-${wiremock.version}-standalone.jar</WIREMOCK_JAR>
+									</environmentVariables>
+								</configuration>
+								<id>python-test-common</id>
+								<phase>integration-test</phase>
+								<goals>
+									<goal>exec</goal>
+								</goals>
+							</execution>
+							<execution>
+								<configuration>
+									<executable>python</executable>
+									<workingDirectory>src/test/python</workingDirectory>
+									<!-- interactive use cases -->
+									<arguments>
+										<argument>test_interactive.py</argument>
+									</arguments>
+									<environmentVariables>
+										<PYTHONPATH>../../main/python:$PYTHONPATH</PYTHONPATH>
+										<CLI_JAR>${project.build.directory}/${project.build.finalName}.jar</CLI_JAR>
+										<WIREMOCK_JAR>${project.build.directory}/dependency/wiremock-${wiremock.version}-standalone.jar</WIREMOCK_JAR>
+									</environmentVariables>
+								</configuration>
+								<id>python-test-interactive</id>
+								<phase>integration-test</phase>
+								<goals>
+									<goal>exec</goal>
+								</goals>
+							</execution>
+							<execution>
+								<configuration>
+									<executable>python</executable>
+									<workingDirectory>src/test/python</workingDirectory>
+									<!-- non-interactive use cases -->
+									<arguments>
+										<argument>test_noninteractive.py</argument>
+									</arguments>
+									<environmentVariables>
+										<PYTHONPATH>../../main/python:$PYTHONPATH</PYTHONPATH>
+										<CLI_JAR>${project.build.directory}/${project.build.finalName}.jar</CLI_JAR>
+										<WIREMOCK_JAR>${project.build.directory}/dependency/wiremock-${wiremock.version}-standalone.jar</WIREMOCK_JAR>
+									</environmentVariables>
+								</configuration>
+								<id>python-test-noninteractive</id>
+								<phase>integration-test</phase>
+								<goals>
+									<goal>exec</goal>
+								</goals>
+							</execution>
+						</executions>
+					</plugin>
+				</plugins>
+			</build>
+		</profile>
+	</profiles>
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cb3a22e8/components/org.apache.stratos.cli/src/test/python/.gitignore
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/src/test/python/.gitignore b/components/org.apache.stratos.cli/src/test/python/.gitignore
new file mode 100644
index 0000000..9ef57cb
--- /dev/null
+++ b/components/org.apache.stratos.cli/src/test/python/.gitignore
@@ -0,0 +1,20 @@
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you 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.
+#
+
+*.pyc

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cb3a22e8/components/org.apache.stratos.cli/src/test/python/__files/body_cookie.json
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/src/test/python/__files/body_cookie.json b/components/org.apache.stratos.cli/src/test/python/__files/body_cookie.json
new file mode 100644
index 0000000..33924ae
--- /dev/null
+++ b/components/org.apache.stratos.cli/src/test/python/__files/body_cookie.json
@@ -0,0 +1 @@
+{"Success":{ "sessionId": "BD425955D0F64102B3C67B39D0C946F0"}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cb3a22e8/components/org.apache.stratos.cli/src/test/python/__files/body_tenant_create.json
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/src/test/python/__files/body_tenant_create.json b/components/org.apache.stratos.cli/src/test/python/__files/body_tenant_create.json
new file mode 100644
index 0000000..8ab5eb1
--- /dev/null
+++ b/components/org.apache.stratos.cli/src/test/python/__files/body_tenant_create.json
@@ -0,0 +1 @@
+{"stratosAdminResponse":{"message":"Successfully added new tenant with domain tenant.com"}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cb3a22e8/components/org.apache.stratos.cli/src/test/python/__files/body_tenant_deactivate.json
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/src/test/python/__files/body_tenant_deactivate.json b/components/org.apache.stratos.cli/src/test/python/__files/body_tenant_deactivate.json
new file mode 100644
index 0000000..d323d70
--- /dev/null
+++ b/components/org.apache.stratos.cli/src/test/python/__files/body_tenant_deactivate.json
@@ -0,0 +1 @@
+{"stratosAdminResponse":{"message":"Successfully deactivated tenant tenant.com"}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cb3a22e8/components/org.apache.stratos.cli/src/test/python/__files/body_tenant_list.json
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/src/test/python/__files/body_tenant_list.json b/components/org.apache.stratos.cli/src/test/python/__files/body_tenant_list.json
new file mode 100644
index 0000000..5952ccb
--- /dev/null
+++ b/components/org.apache.stratos.cli/src/test/python/__files/body_tenant_list.json
@@ -0,0 +1 @@
+{"tenantInfoBean":[{"active":true,"createdDate":"2014-05-09T05:40:11Z","email":"john@tenant.com","tenantDomain":"tenant.com","tenantId":1}]}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cb3a22e8/components/org.apache.stratos.cli/src/test/python/__init__.py
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/src/test/python/__init__.py b/components/org.apache.stratos.cli/src/test/python/__init__.py
new file mode 100644
index 0000000..314303d
--- /dev/null
+++ b/components/org.apache.stratos.cli/src/test/python/__init__.py
@@ -0,0 +1,19 @@
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you 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.
+#
+

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cb3a22e8/components/org.apache.stratos.cli/src/test/python/mappings/cookie.json
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/src/test/python/mappings/cookie.json b/components/org.apache.stratos.cli/src/test/python/mappings/cookie.json
new file mode 100644
index 0000000..31336ba
--- /dev/null
+++ b/components/org.apache.stratos.cli/src/test/python/mappings/cookie.json
@@ -0,0 +1,18 @@
+{
+  "request" : {
+    "url" : "/stratos/admin/cookie",
+    "method" : "GET"
+  },
+  "response" : {
+    "status" : 200,
+    "bodyFileName" : "body_cookie.json",
+    "headers" : {
+      "Set-Cookie" : "JSESSIONID=BD425955D0F64102B3C67B39D0C946F0; Path=/stratos/; Secure; HttpOnly",
+      "Date" : "Fri, 09 May 2014 05:40:05 GMT",
+      "WWW-Authenticate" : "Basic",
+      "Content-Type" : "application/json",
+      "Content-Length" : "62",
+      "Server" : "WSO2 Carbon Server"
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cb3a22e8/components/org.apache.stratos.cli/src/test/python/mappings/tenant-create.json
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/src/test/python/mappings/tenant-create.json b/components/org.apache.stratos.cli/src/test/python/mappings/tenant-create.json
new file mode 100644
index 0000000..3f3ce05
--- /dev/null
+++ b/components/org.apache.stratos.cli/src/test/python/mappings/tenant-create.json
@@ -0,0 +1,19 @@
+{
+  "request" : {
+    "url" : "/stratos/admin/tenant",
+    "method" : "POST",
+    "bodyPatterns" : [ {
+      "equalTo" : "{\"admin\":\"tenant1\",\"firstname\":\"John\",\"lastname\":\"Doe\",\"adminPassword\":\"secret\",\"tenantDomain\":\"tenant.com\",\"email\":\"john@tenant.com\",\"active\":false,\"tenantId\":0}"
+    } ]
+  },
+  "response" : {
+    "status" : 200,
+    "bodyFileName" : "body_tenant_create.json",
+    "headers" : {
+      "Date" : "Fri, 09 May 2014 05:40:12 GMT",
+      "Content-Type" : "application/json",
+      "Transfer-Encoding" : "chunked",
+      "Server" : "WSO2 Carbon Server"
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cb3a22e8/components/org.apache.stratos.cli/src/test/python/mappings/tenant-deactivate.json
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/src/test/python/mappings/tenant-deactivate.json b/components/org.apache.stratos.cli/src/test/python/mappings/tenant-deactivate.json
new file mode 100644
index 0000000..4691f6b
--- /dev/null
+++ b/components/org.apache.stratos.cli/src/test/python/mappings/tenant-deactivate.json
@@ -0,0 +1,16 @@
+{
+  "request" : {
+    "url" : "/stratos/admin/tenant/deactivate/tenant.com",
+    "method" : "POST"
+  },
+  "response" : {
+    "status" : 200,
+    "bodyFileName" : "body_tenant_deactivate.json",
+    "headers" : {
+      "Date" : "Sat, 10 May 2014 10:07:14 GMT",
+      "Content-Type" : "application/json",
+      "Transfer-Encoding" : "chunked",
+      "Server" : "WSO2 Carbon Server"
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cb3a22e8/components/org.apache.stratos.cli/src/test/python/mappings/tenant-list.json
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/src/test/python/mappings/tenant-list.json b/components/org.apache.stratos.cli/src/test/python/mappings/tenant-list.json
new file mode 100644
index 0000000..36588cd
--- /dev/null
+++ b/components/org.apache.stratos.cli/src/test/python/mappings/tenant-list.json
@@ -0,0 +1,16 @@
+{
+  "request" : {
+    "url" : "/stratos/admin/tenant/list",
+    "method" : "GET"
+  },
+  "response" : {
+    "status" : 200,
+    "bodyFileName" : "body_tenant_list.json",
+    "headers" : {
+      "Date" : "Fri, 09 May 2014 05:45:15 GMT",
+      "Content-Type" : "application/json",
+      "Transfer-Encoding" : "chunked",
+      "Server" : "WSO2 Carbon Server"
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cb3a22e8/components/org.apache.stratos.cli/src/test/python/test_common.py
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/src/test/python/test_common.py b/components/org.apache.stratos.cli/src/test/python/test_common.py
new file mode 100755
index 0000000..407a178
--- /dev/null
+++ b/components/org.apache.stratos.cli/src/test/python/test_common.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python 
+# ----------------------------------------------------------------------------
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+import unittest
+import pexpect
+import os
+import signal
+import subprocess
+import urllib
+import urllib2
+import json
+from wiremock import WiremockClient
+
+class TestCommon(unittest.TestCase):
+
+    cli_cmd = "java -jar " + os.environ["CLI_JAR"]
+
+    @classmethod
+    def setUpClass(cls):
+        TestCommon.wiremock = WiremockClient()
+        TestCommon.wiremock.start()
+
+    @classmethod
+    def tearDownClass(cls):
+        TestCommon.wiremock.stop()
+
+    def setUp(self):
+        # unset these environment variables
+        if 'STRATOS_USERNAME' in os.environ: del os.environ["STRATOS_USERNAME"] # unset env var
+        if 'STRATOS_PASSWORD' in os.environ: del os.environ["STRATOS_PASSWORD"] # unset env var
+
+    def tearDown(self):
+        TestCommon.wiremock.reset()
+
+    def test_error_if_stratos_url_not_set(self):
+        if 'STRATOS_URL' in os.environ: del os.environ["STRATOS_URL"]      # unset env var
+        child = pexpect.spawn(TestCommon.cli_cmd)
+        child.expect ('Could not find required "STRATOS_URL" variable in your environment.')
+        child.expect (pexpect.EOF)
+
+    def test_error_if_port_not_provided_in_stratos_url(self):
+        os.environ["STRATOS_URL"] = "https://localhost"  # no port
+        child = pexpect.spawn(TestCommon.cli_cmd)
+        child.expect ('The "STRATOS_URL" variable in your environment is not a valid URL. You have provided "https://localhost"')
+        child.expect ('Please provide the Stratos Controller URL as follows')
+        child.expect ('https://<host>:<port>')
+        child.expect (pexpect.EOF)
+
+    def test_error_if_context_path_is_provided_in_stratos_url(self):
+        os.environ["STRATOS_URL"] = "https://localhost:9443/somecontext/" # context path
+        child = pexpect.spawn(TestCommon.cli_cmd)
+        child.expect ('The "STRATOS_URL" variable in your environment is not a valid URL. You have provided "https://localhost:9443/somecontext/"')
+        child.expect ('Please provide the Stratos Controller URL as follows')
+        child.expect ('https://<host>:<port>')
+        child.expect (pexpect.EOF)
+
+    def test_error_if_non_https_scheme_is_provided_in_stratos_url(self):
+        os.environ["STRATOS_URL"] = "http://localhost:9443" # http scheme
+        child = pexpect.spawn(TestCommon.cli_cmd)
+        child.expect ('The "STRATOS_URL" variable in your environment is not a valid URL. You have provided "http://localhost:9443"')
+        child.expect ('Please provide the Stratos Controller URL as follows')
+        child.expect ('https://<host>:<port>')
+        child.expect (pexpect.EOF)
+
+    def test_error_if_invalid_format_is_given_for_stratos_url(self):
+        # we need to ensure the url is valid and not that it just has 2 colons and 3 or less slashes!
+        os.environ["STRATOS_URL"] = ":://"
+        child = pexpect.spawn(TestCommon.cli_cmd)
+        child.expect ('The "STRATOS_URL" variable in your environment is not a valid URL. You have provided ":://"')
+        child.expect ('Please provide the Stratos Controller URL as follows')
+        child.expect ('https://<host>:<port>')
+        child.expect (pexpect.EOF)
+
+if __name__ == '__main__':
+    try: 
+        unittest.main()
+    # handle CTRL-C
+    except KeyboardInterrupt:
+        # shut down wiremock 
+        TestCommon.wiremock.stop()
+        exit(1) 

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cb3a22e8/components/org.apache.stratos.cli/src/test/python/test_interactive.py
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/src/test/python/test_interactive.py b/components/org.apache.stratos.cli/src/test/python/test_interactive.py
new file mode 100755
index 0000000..cf1bb3e
--- /dev/null
+++ b/components/org.apache.stratos.cli/src/test/python/test_interactive.py
@@ -0,0 +1,195 @@
+#!/usr/bin/env python 
+# ----------------------------------------------------------------------------
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+import unittest
+import pexpect
+import os
+import signal
+import subprocess
+import urllib
+import urllib2
+import json
+from wiremock import WiremockClient
+
+class TestInteractive(unittest.TestCase):
+
+    cli_cmd = "java -jar " + os.environ["CLI_JAR"]
+
+    @classmethod
+    def setUpClass(cls):
+        TestInteractive.wiremock = WiremockClient()
+        TestInteractive.wiremock.start()
+
+    @classmethod
+    def tearDownClass(cls):
+        TestInteractive.wiremock.stop()
+
+    def setUp(self):
+        # set default STRATOS_URL
+        os.environ["STRATOS_URL"] = "https://localhost:9443" 
+        # ensure other env vars not set
+        if 'STRATOS_USERNAME' in os.environ: del os.environ["STRATOS_USERNAME"] # unset env var
+        if 'STRATOS_PASSWORD' in os.environ: del os.environ["STRATOS_PASSWORD"] # unset env var
+
+    def tearDown(self):
+        TestInteractive.wiremock.reset()
+
+    def test_interactive_mode_username_and_password_sent_to_server(self):
+        child = pexpect.spawn(TestInteractive.cli_cmd)
+        child.expect   ('Username: ')
+        child.sendline ('1234')
+        child.expect   ('Password: ')
+        child.sendline ('abcd')
+        child.expect   ('Successfully Authenticated.')
+        child.expect   ('stratos> ')
+        child.sendline ('exit')
+        child.expect   (pexpect.EOF)
+        # CLI sends GET request to mock server url /stratos/admin/coookie
+        self.assertEqual(self.wiremock.get_cookie_auth_header(), "1234:abcd")
+
+    def test_interactive_mode_standard_username_parameter_provided(self):
+        child = pexpect.spawn(TestInteractive.cli_cmd + " -username xxx", timeout=10)
+        child.expect   ('Username: xxx')
+        child.expect   ('Password: ')
+        child.sendline ('zzz')
+        child.expect   ('Successfully Authenticated.')
+        child.expect   ('stratos> ')
+        child.sendline ('exit')
+        child.expect   (pexpect.EOF)
+        # CLI sends GET request to mock server url /stratos/admin/coookie
+        self.assertEqual(self.wiremock.get_cookie_auth_header(), "xxx:zzz")
+
+    def test_interactive_mode_short_username_parameter_provided(self):
+        child = pexpect.spawn(TestInteractive.cli_cmd + " -u xxx", timeout=10)
+        child.expect   ('Username: xxx')
+        child.expect   ('Password: ')
+        child.sendline ('zzz')
+        child.expect   ('Successfully Authenticated.')
+        child.expect   ('stratos> ')
+        child.sendline ('exit')
+        child.expect   (pexpect.EOF)
+        # CLI sends GET request to mock server url /stratos/admin/coookie
+        self.assertEqual(self.wiremock.get_cookie_auth_header(), "xxx:zzz")
+
+    def test_interactive_mode_long_username_parameter_provided(self):
+        child = pexpect.spawn(TestInteractive.cli_cmd + " --username xxx", timeout=10)
+        child.expect   ('Username: xxx')
+        child.expect   ('Password: ')
+        child.sendline ('zzz')
+        child.expect   ('Successfully Authenticated.')
+        child.expect   ('stratos> ')
+        child.sendline ('exit')
+        child.expect   (pexpect.EOF)
+        # CLI sends GET request to mock server url /stratos/admin/coookie
+        self.assertEqual(self.wiremock.get_cookie_auth_header(), "xxx:zzz")
+
+    def test_interactive_mode_username_env_var_provided(self):
+        os.environ["STRATOS_USERNAME"] = "yyy" 
+        # ensure other env vars not set
+        child = pexpect.spawn(TestInteractive.cli_cmd, timeout=10)
+        child.expect   ('Username: yyy')
+        child.expect   ('Password: ')
+        child.sendline ('zzz')
+        child.expect   ('Successfully Authenticated.')
+        child.expect   ('stratos> ')
+        child.sendline ('exit')
+        child.expect   (pexpect.EOF)
+        # CLI sends GET request to mock server url /stratos/admin/coookie
+        self.assertEqual(self.wiremock.get_cookie_auth_header(), "yyy:zzz")
+
+    def test_interactive_mode_standard_password_parameter_provided(self):
+        child = pexpect.spawn(TestInteractive.cli_cmd + " -password xxx", timeout=10)
+        child.expect   ('Username: ')
+        child.sendline ('1234') 
+        child.expect   ('Successfully Authenticated.')
+        child.expect   ('stratos> ')
+        child.sendline ('exit')
+        child.expect   (pexpect.EOF)
+        # CLI sends GET request to mock server url /stratos/admin/coookie
+        self.assertEqual(self.wiremock.get_cookie_auth_header(), "1234:xxx")
+
+    def test_interactive_mode_list_tenants(self):
+        child = pexpect.spawn(TestInteractive.cli_cmd, timeout=10)
+        child.expect   ('Username: ')
+        child.sendline ('1234') 
+        child.expect   ('\r\nPassword: ') # TODO - why do we need \r\n?
+        child.sendline ('zzz')
+        child.expect   ('Successfully Authenticated.')
+        child.expect   ('stratos> ')
+        child.sendline ('list-tenants')
+        child.expect   ('Available Tenants')
+        # in the table below, + characters have been replaced with .
+        # because the + is a special regex character
+        child.expect   ('.------------.-----------.-----------------.--------.----------------------.')
+        child.expect   ('| Domain     | Tenant ID | Email           | State  | Created Date         |')
+        child.expect   ('.------------.-----------.-----------------.--------.----------------------.')
+        child.expect   ('| tenant.com | 1         | john@tenant.com | Active | 2014-05-09T05:40:11Z |')
+        child.expect   ('.------------.-----------.-----------------.--------.----------------------.')
+        child.sendline ('exit')
+        child.expect   (pexpect.EOF)
+        # CLI sends GET request to mock server url /stratos/admin/coookie
+        self.assertEqual(self.wiremock.get_cookie_auth_header(), "1234:zzz")
+        self.assertEqual(self.wiremock.get_cookie_req_count(), 1)
+        self.assertEqual(self.wiremock.get_tenant_list_req_count(), 1)
+
+    def test_interactive_mode_create_tenant(self):
+        child = pexpect.spawn(TestInteractive.cli_cmd, timeout=10)
+        child.expect   ('Username: ')
+        child.sendline ('1234') 
+        child.expect   ('\r\nPassword: ') # TODO - why do we need \r\n?
+        child.sendline ('zzz')
+        child.expect   ('Successfully Authenticated.')
+        child.expect   ('stratos> ')
+        child.sendline ('create-tenant --username tenant1 --password secret --first-name John --last-name Doe --domain-name tenant.com --email john@tenant.com')
+        child.expect   ('Tenant added successfully')
+        child.sendline ('exit')
+        child.expect   (pexpect.EOF)
+        # CLI sends GET request to mock server url /stratos/admin/coookie
+        self.assertEqual(self.wiremock.get_cookie_auth_header(), "1234:zzz")
+        self.assertEqual(self.wiremock.get_cookie_req_count(), 1)
+        self.assertEqual(self.wiremock.tenant_create_req_count(), 1)
+
+    def test_interactive_mode_deactivate_tenant(self):
+        child = pexpect.spawn(TestInteractive.cli_cmd, timeout=10)
+        child.expect   ('Username: ')
+        child.sendline ('1234') 
+        child.expect   ('\r\nPassword: ') # TODO - why do we need \r\n?
+        child.sendline ('zzz')
+        child.expect   ('Successfully Authenticated.')
+        child.expect   ('stratos> ')
+        child.sendline ('deactivate-tenant tenant.com')
+        child.expect   ('You have succesfully deactivate tenant.com tenant')
+        child.sendline ('exit')
+        child.expect   (pexpect.EOF)
+        # CLI sends GET request to mock server url /stratos/admin/coookie
+        self.assertEqual(self.wiremock.get_cookie_auth_header(), "1234:zzz")
+        self.assertEqual(self.wiremock.get_cookie_req_count(), 1)
+        self.assertEqual(self.wiremock.tenant_deactivate_req_count(), 1)
+
+
+if __name__ == '__main__':
+    try: 
+        unittest.main()
+    # handle CTRL-C
+    except KeyboardInterrupt:
+        # shut down wiremock 
+        TestInteractive.wiremock.stop()
+        exit(1) 

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cb3a22e8/components/org.apache.stratos.cli/src/test/python/test_noninteractive.py
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/src/test/python/test_noninteractive.py b/components/org.apache.stratos.cli/src/test/python/test_noninteractive.py
new file mode 100755
index 0000000..8379165
--- /dev/null
+++ b/components/org.apache.stratos.cli/src/test/python/test_noninteractive.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python 
+# ----------------------------------------------------------------------------
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+import unittest
+import pexpect
+import os
+import signal
+import subprocess
+import urllib
+import urllib2
+import json
+from wiremock import WiremockClient
+
+class TestNonInteractive(unittest.TestCase):
+
+    cli_cmd = "java -jar " + os.environ["CLI_JAR"]
+
+    @classmethod
+    def setUpClass(cls):
+        TestNonInteractive.wiremock = WiremockClient()
+        TestNonInteractive.wiremock.start()
+
+    @classmethod
+    def tearDownClass(cls):
+        TestNonInteractive.wiremock.stop()
+
+    def setUp(self):
+        # set default STRATOS_URL
+        os.environ["STRATOS_URL"] = "https://localhost:9443" 
+        # ensure other env vars not set
+        if 'STRATOS_USERNAME' in os.environ: del os.environ["STRATOS_USERNAME"] # unset env var
+        if 'STRATOS_PASSWORD' in os.environ: del os.environ["STRATOS_PASSWORD"] # unset env var
+
+    def tearDown(self):
+        TestNonInteractive.wiremock.reset()
+
+    def test_noninteractive_mode_list_tenants(self):
+        child = pexpect.spawn(TestNonInteractive.cli_cmd + " -username admin -password admin list-tenants", timeout=10)
+        child.expect   ('Available Tenants')
+        # in the table below, + characters have been replaced with .
+        # because the + is a special regex character
+        child.expect   ('.------------.-----------.-----------------.--------.----------------------.')
+        child.expect   ('| Domain     | Tenant ID | Email           | State  | Created Date         |')
+        child.expect   ('.------------.-----------.-----------------.--------.----------------------.')
+        child.expect   ('| tenant.com | 1         | john@tenant.com | Active | 2014-05-09T05:40:11Z |')
+        child.expect   ('.------------.-----------.-----------------.--------.----------------------.')
+        child.sendline ('exit')
+        child.expect   (pexpect.EOF)
+        # verify /stratos/admin/tenant/list was called
+        self.assertEqual(self.wiremock.get_tenant_list_req_count(), 1)
+
+    def test_noninteractive_mode_create_tenant(self):
+        command = "create-tenant -u tenant1 -p secret -f John -l Doe -d tenant.com -e john@tenant.com"
+        child = pexpect.spawn(TestNonInteractive.cli_cmd + " -u adminuser -p adminpass " + command, timeout=10)
+        child.expect   ('Username: adminuser')
+        child.expect   ('Tenant added successfully')
+        child.sendline ('exit')
+        child.expect   (pexpect.EOF)
+        # verify POST /stratos/admin/tenant/list was called
+        self.assertEqual(self.wiremock.tenant_create_req_count(), 1)
+
+if __name__ == '__main__':
+    try: 
+        unittest.main()
+    # handle CTRL-C
+    except KeyboardInterrupt:
+        # shut down wiremock 
+        TestNonInteractive.wiremock.stop()
+        exit(1) 

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cb3a22e8/components/org.apache.stratos.cli/src/test/python/wiremock.py
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/src/test/python/wiremock.py b/components/org.apache.stratos.cli/src/test/python/wiremock.py
new file mode 100755
index 0000000..aa81e7f
--- /dev/null
+++ b/components/org.apache.stratos.cli/src/test/python/wiremock.py
@@ -0,0 +1,106 @@
+#!/usr/bin/env python 
+# ----------------------------------------------------------------------------
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+import os
+import signal
+import subprocess
+import urllib
+import urllib2
+import json
+import base64
+
+class WiremockClient():
+
+    reset_url = 'http://localhost:8080/__admin/mappings/reset'
+
+    find_url = 'http://localhost:8080/__admin/requests/find'
+
+    count_url = 'http://localhost:8080/__admin/requests/count'
+
+    cookies_req_json = '{ "method": "GET", "url": "/stratos/admin/cookie" }'
+
+    tenant_list_req_json = '{ "method": "GET", "url": "/stratos/admin/tenant/list" }'
+
+    tenant_create_req_json = '{ "method": "POST", "url": "/stratos/admin/tenant" }'
+
+    tenant_deactivate_req_json = '{ "method": "POST", "url": "/stratos/admin/tenant/deactivate/tenant.com" }'
+
+    wiremock = "java -jar " + os.environ["WIREMOCK_JAR"] + " --https-port 9443"
+
+    def start(self):
+        # execute wiremock and return handle so it can be torn down
+        # Note: the requests that wiremock handles and the response it will return 
+        # for a request can be found in the 'mapping' directory
+        self.wiremock_process = subprocess.Popen(self.wiremock.split(), 
+                               stdout=subprocess.PIPE, 
+                               preexec_fn=os.setsid) 
+
+    def __del__(self):
+        self.stop()
+
+    def stop(self):
+        # kill wiremock process
+        os.killpg(self.wiremock_process.pid, signal.SIGTERM)
+
+    def reset(self):
+        # ignore errors when resetting
+        try:
+            req = urllib2.Request(WiremockClient.reset_url, data="")
+            urllib2.urlopen(req)
+        except:
+            pass
+
+    def get_cookie_requests_and_responses(self):
+        # send GET request to mock server url /stratos/admin/coookie
+        req = urllib2.Request(WiremockClient.find_url)
+        req.add_header('Content-Type', 'application/json')
+        response = urllib2.urlopen(req, WiremockClient.cookies_req_json)
+        return json.load(response)
+
+    def get_cookie_auth_header(self):
+        data = self.get_cookie_requests_and_responses()
+        encoded_username_password = data["requests"][0]["headers"]["Authorization"]
+        return base64.b64decode(encoded_username_password.split(" ")[1])
+   
+    # lots of repeated code below - TODO refactor to method
+    def get_cookie_req_count(self):
+        req = urllib2.Request(WiremockClient.count_url)
+        req.add_header('Content-Type', 'application/json')
+        response = urllib2.urlopen(req, WiremockClient.cookies_req_json)
+        return json.load(response)["count"]
+
+    def get_tenant_list_req_count(self):
+        req = urllib2.Request(WiremockClient.count_url)
+        req.add_header('Content-Type', 'application/json')
+        response = urllib2.urlopen(req, WiremockClient.tenant_list_req_json)
+        return json.load(response)["count"]
+             
+    def tenant_create_req_count(self):
+        req = urllib2.Request(WiremockClient.count_url)
+        req.add_header('Content-Type', 'application/json')
+        response = urllib2.urlopen(req, WiremockClient.tenant_create_req_json)
+        return json.load(response)["count"]
+
+    def tenant_deactivate_req_count(self):
+        req = urllib2.Request(WiremockClient.count_url)
+        req.add_header('Content-Type', 'application/json')
+        response = urllib2.urlopen(req, WiremockClient.tenant_deactivate_req_json)
+        return json.load(response)["count"]


[2/4] git commit: fixing https://issues.apache.org/jira/browse/STRATOS-650

Posted by ch...@apache.org.
fixing https://issues.apache.org/jira/browse/STRATOS-650


Project: http://git-wip-us.apache.org/repos/asf/incubator-stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-stratos/commit/8255890e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-stratos/tree/8255890e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-stratos/diff/8255890e

Branch: refs/heads/master
Commit: 8255890eee47f16c981fce463108a28de3e44613
Parents: cb3a22e
Author: Chris Snow <ch...@gmail.com>
Authored: Sun May 11 06:01:55 2014 +0000
Committer: Chris Snow <ch...@gmail.com>
Committed: Sun May 11 06:08:55 2014 +0000

----------------------------------------------------------------------
 .../src/main/java/org/apache/stratos/cli/StratosApplication.java   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/8255890e/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/StratosApplication.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/StratosApplication.java b/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/StratosApplication.java
index e4bc0c0..dc76667 100644
--- a/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/StratosApplication.java
+++ b/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/StratosApplication.java
@@ -279,7 +279,7 @@ public class StratosApplication extends CommandLineApplication<StratosCommandCon
 					allCommandOptions.addOption((Option) o);
 				}
 				
-				commandLine = parser.parse(allCommandOptions, args);
+				commandLine = parser.parse(options, args, true);
 				remainingArgs = commandLine.getArgs();
 				if (remainingArgs != null && remainingArgs.length > 0) {
 					// Get command action


[3/4] git commit: download and setup pexpect library

Posted by ch...@apache.org.
download and setup pexpect library


Project: http://git-wip-us.apache.org/repos/asf/incubator-stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-stratos/commit/50849a6f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-stratos/tree/50849a6f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-stratos/diff/50849a6f

Branch: refs/heads/master
Commit: 50849a6f957db632a1a1fd30ac1840dd5024ed1d
Parents: 8255890
Author: Chris Snow <ch...@apache.org>
Authored: Wed May 14 06:33:41 2014 +0000
Committer: Chris Snow <ch...@apache.org>
Committed: Wed May 14 06:33:41 2014 +0000

----------------------------------------------------------------------
 components/org.apache.stratos.cli/pom.xml | 30 +++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/50849a6f/components/org.apache.stratos.cli/pom.xml
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/pom.xml b/components/org.apache.stratos.cli/pom.xml
index 62b9e97..8abe1b9 100644
--- a/components/org.apache.stratos.cli/pom.xml
+++ b/components/org.apache.stratos.cli/pom.xml
@@ -180,6 +180,30 @@
 			<build>
 				<plugins>
 					<plugin>
+						<artifactId>maven-antrun-plugin</artifactId>
+						<version>1.7</version>
+						<executions>
+							<execution>
+								<phase>pre-integration-test</phase>
+								<configuration>
+									<tasks>
+										<mkdir dir="${project.build.directory}/downloads/"/>
+										<get src="https://pypi.python.org/packages/source/p/pexpect/pexpect-3.2.tar.gz" 
+											dest="${project.build.directory}/downloads/"
+											verbose="true"/>
+										<gunzip src="${project.build.directory}/downloads/pexpect-3.2.tar.gz" 
+											dest="${project.build.directory}/downloads/pexpect-3.2.tar"/>
+										<untar src="${project.build.directory}/downloads/pexpect-3.2.tar" 
+											dest="${project.build.directory}/"/>
+									</tasks>
+								</configuration>
+								<goals>
+									<goal>run</goal>
+ 								</goals>
+							</execution>
+						</executions>
+					</plugin>
+					<plugin>
 						<groupId>org.codehaus.mojo</groupId>
 						<artifactId>exec-maven-plugin</artifactId>
 						<version>1.3</version>
@@ -193,7 +217,7 @@
 										<argument>test_common.py</argument>
 									</arguments>
 									<environmentVariables>
-										<PYTHONPATH>../../main/python:$PYTHONPATH</PYTHONPATH>
+										<PYTHONPATH>../../main/python:${project.build.directory}/pexpect-3.2:$PYTHONPATH</PYTHONPATH>
 										<CLI_JAR>${project.build.directory}/${project.build.finalName}.jar</CLI_JAR>
 										<WIREMOCK_JAR>${project.build.directory}/dependency/wiremock-${wiremock.version}-standalone.jar</WIREMOCK_JAR>
 									</environmentVariables>
@@ -213,7 +237,7 @@
 										<argument>test_interactive.py</argument>
 									</arguments>
 									<environmentVariables>
-										<PYTHONPATH>../../main/python:$PYTHONPATH</PYTHONPATH>
+										<PYTHONPATH>../../main/python:${project.build.directory}/pexpect-3.2:$PYTHONPATH</PYTHONPATH>
 										<CLI_JAR>${project.build.directory}/${project.build.finalName}.jar</CLI_JAR>
 										<WIREMOCK_JAR>${project.build.directory}/dependency/wiremock-${wiremock.version}-standalone.jar</WIREMOCK_JAR>
 									</environmentVariables>
@@ -233,7 +257,7 @@
 										<argument>test_noninteractive.py</argument>
 									</arguments>
 									<environmentVariables>
-										<PYTHONPATH>../../main/python:$PYTHONPATH</PYTHONPATH>
+										<PYTHONPATH>../../main/python:${project.build.directory}/pexpect-3.2:$PYTHONPATH</PYTHONPATH>
 										<CLI_JAR>${project.build.directory}/${project.build.finalName}.jar</CLI_JAR>
 										<WIREMOCK_JAR>${project.build.directory}/dependency/wiremock-${wiremock.version}-standalone.jar</WIREMOCK_JAR>
 									</environmentVariables>


[4/4] git commit: Merge remote-tracking branch 'origin/stratos-651-cli-test-suite'

Posted by ch...@apache.org.
Merge remote-tracking branch 'origin/stratos-651-cli-test-suite'


Project: http://git-wip-us.apache.org/repos/asf/incubator-stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-stratos/commit/0f6cfd3f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-stratos/tree/0f6cfd3f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-stratos/diff/0f6cfd3f

Branch: refs/heads/master
Commit: 0f6cfd3fa361fdc627c49aa65dff9c0189ff4374
Parents: 160a6e4 50849a6
Author: Chris Snow <ch...@apache.org>
Authored: Wed May 14 18:27:07 2014 +0000
Committer: Chris Snow <ch...@apache.org>
Committed: Wed May 14 18:27:07 2014 +0000

----------------------------------------------------------------------
 components/org.apache.stratos.cli/README.md     |   7 +
 components/org.apache.stratos.cli/pom.xml       | 142 +++++++++++++-
 .../src/test/python/.gitignore                  |  20 ++
 .../src/test/python/__files/body_cookie.json    |   1 +
 .../test/python/__files/body_tenant_create.json |   1 +
 .../python/__files/body_tenant_deactivate.json  |   1 +
 .../test/python/__files/body_tenant_list.json   |   1 +
 .../src/test/python/__init__.py                 |  19 ++
 .../src/test/python/mappings/cookie.json        |  18 ++
 .../src/test/python/mappings/tenant-create.json |  19 ++
 .../test/python/mappings/tenant-deactivate.json |  16 ++
 .../src/test/python/mappings/tenant-list.json   |  16 ++
 .../src/test/python/test_common.py              |  99 ++++++++++
 .../src/test/python/test_interactive.py         | 195 +++++++++++++++++++
 .../src/test/python/test_noninteractive.py      |  87 +++++++++
 .../src/test/python/wiremock.py                 | 106 ++++++++++
 16 files changed, 747 insertions(+), 1 deletion(-)
----------------------------------------------------------------------