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/11 07:57:44 UTC
git commit: added integration test suite
Repository: incubator-stratos
Updated Branches:
refs/heads/stratos-651-cli-test-suite [created] cb3a22e8c
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/stratos-651-cli-test-suite
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"]