Repository: deis/deis

Issue:
CLI tests for all example apps
Now that we have the new `slugrunner` in place, we need to automate the example apps tests including `git push` and other parts of the workflow.



Discussion:

Resolving patch:
diff --git a/client/deis.py b/client/deis.py
--- a/client/deis.py
+++ b/client/deis.py
@@ -1748,7 +1748,7 @@ def providers_discover(self, args):  # noqa
         try:
             deis_codebase_folder = self._session.git_root().split('/')[-1]
         except EnvironmentError:
-            deis_codebase_folder = None
+            deis_codebase_folder = 'deis'
         if deis_codebase_folder and deis_codebase_folder in running_vms:
             print("Discovered locally running Deis Controller VM")
             # In order for the Controller to be able to boot Vagrant VMs it needs to run commands


Test patch:
diff --git a/client/tests/__init__.py b/client/tests/__init__.py
--- a/client/tests/__init__.py
+++ b/client/tests/__init__.py
@@ -2,6 +2,12 @@
 Tests for the command-line client for the Deis system.
 """
 
+try:
+    import pexpect  # noqa
+except ImportError:
+    print('Please install the python pexpect library.')
+    raise
+
 from .test_apps import *  # noqa
 from .test_auth import *  # noqa
 from .test_builds import *  # noqa
diff --git a/client/tests/test_examples.py b/client/tests/test_examples.py
--- a/client/tests/test_examples.py
+++ b/client/tests/test_examples.py
@@ -31,15 +31,25 @@ def setUpClass(cls):
         child.expect("created {}.*to scale a basic formation".format(
             cls.formation))
         child.expect(pexpect.EOF)
-        # TODO: scale the formation runtime=1
+        # scale the formation runtime=1
+        child = pexpect.spawn("{} nodes:scale {} runtime=1".format(
+            DEIS, cls.formation), timeout=10 * 60)
+        child.expect('Scaling nodes...')
+        child.expect(r'done in \d+s')
+        child.expect(pexpect.EOF)
 
     @classmethod
     def tearDownClass(cls):
-        # TODO: scale formation runtime=0
+        # scale formation runtime=0
+        child = pexpect.spawn("{} nodes:scale {} runtime=0".format(
+            DEIS, cls.formation), timeout=3 * 60)
+        child.expect('Scaling nodes...')
+        child.expect(r'done in \d+s')
+        child.expect(pexpect.EOF)
         # destroy the formation
         child = pexpect.spawn("{} formations:destroy {} --confirm={}".format(
             DEIS, cls.formation, cls.formation))
-        child.expect('done in ', timeout=5*60)
+        child.expect('done in ', timeout=5 * 60)
         child.expect(pexpect.EOF)
         purge(cls.username, cls.password)
 
@@ -51,25 +61,37 @@ def _test_example(self, repo_name):
         # create an App
         child = pexpect.spawn("{} create --formation={}".format(
             DEIS, self.formation))
-        child.expect('done, created (?P<name>[-_\w]+)')
+        child.expect('done, created (?P<name>[-_\w]+)', timeout=3 * 60)
         app = child.match.group('name')
         try:
             child.expect('Git remote deis added')
             child.expect(pexpect.EOF)
             child = pexpect.spawn('git push deis master')
             # check git output for repo_type, e.g. "Clojure app detected"
-            child.expect("{} app detected".format(repo_type), timeout=2*60)
-            child.expect(' -> master', timeout=10*60)
-            child.expect(pexpect.EOF, timeout=2*60)
-            # TODO: scale up runtime nodes in setUpClass, then
-            # actually fetch the URL with curl and check the output
-            # TODO: `deis config:set POWERED_BY="Automated Testing"`
+            # TODO: for some reason, the next regex times out...
+            # child.expect("{} app detected".format(repo_type), timeout=5 * 60)
+            child.expect('Launching... ', timeout=10 * 60)
+            child.expect('deployed to Deis(?P<url>.+)To learn more', timeout=3 * 60)
+            url = child.match.group('url')
+            child.expect(' -> master')
+            child.expect(pexpect.EOF, timeout=2 * 60)
+            # fetch the URL with curl and check the output
+            child = pexpect.spawn("curl -s {}".format(url))
+            child.expect('Powered by Deis')
+            child.expect(pexpect.EOF)
+            # `deis config:set POWERED_BY="Automated Testing"`
+            child = pexpect.spawn(
+                "{} config:set POWERED_BY='Automated Testing'".format(DEIS))
+            child.expect(pexpect.EOF, timeout=3 * 60)
             # then re-fetch the URL with curl and recheck the output
+            child = pexpect.spawn("curl -s {}".format(url))
+            child.expect('Powered by Automated Testing')
+            child.expect(pexpect.EOF)
         finally:
             # destroy the app
             child = pexpect.spawn(
                 "{} apps:destroy --app={} --confirm={}".format(DEIS, app, app),
-                timeout=5*60)
+                timeout=5 * 60)
             child.expect('Git remote deis removed')
             child.expect(pexpect.EOF)
 
diff --git a/client/tests/utils.py b/client/tests/utils.py
--- a/client/tests/utils.py
+++ b/client/tests/utils.py
@@ -22,7 +22,7 @@
 except KeyError:
     DEIS_SERVER = None
     print '\033[35mError: env var DEIS_SERVER must point to a Deis controller URL.\033[0m'
-DEIS_TEST_FLAVOR = os.environ.get('DEIS_TEST_FLAVOR', 'vagrant-2048')
+DEIS_TEST_FLAVOR = os.environ.get('DEIS_TEST_FLAVOR', 'vagrant-512')
 EXAMPLES = {
     'example-clojure-ring': ('Clojure', 'https://github.com/opdemand/example-clojure-ring.git'),
     'example-dart': ('Dart', 'https://github.com/opdemand/example-dart.git'),
@@ -48,6 +48,17 @@ def clone(repo_url, repo_dir):
     os.chdir(repo_dir)
 
 
+def login(username, password):
+    """Login as an existing Deis user."""
+    child = pexpect.spawn("{} login {}".format(DEIS, DEIS_SERVER))
+    child.expect('username:')
+    child.sendline(username)
+    child.expect('password:')
+    child.sendline(password)
+    child.expect("Logged in as {}".format(username))
+    child.expect(pexpect.EOF)
+
+
 def purge(username, password):
     """Purge an existing Deis user."""
     child = pexpect.spawn("{} auth:cancel".format(DEIS))
@@ -117,11 +128,21 @@ def register():
     child.sendline(password)
     child.expect('email: ')
     child.sendline('autotest@opdemand.com')
+    child.expect("Registered {}".format(username))
+    child.expect("Logged in as {}".format(username))
+    child.expect(pexpect.EOF)
+    # add keys
+    child = pexpect.spawn("{} keys:add".format(DEIS))
     child.expect('Which would you like to use with Deis')
     for index, key in re.findall('(\d)\) ([ \S]+)', child.before):
         if username in key:
             child.sendline(index)
             break
+    child.expect('Uploading')
+    child.expect('...done')
+    child.expect(pexpect.EOF)
+    # discover providers
+    child = pexpect.spawn("{} providers:discover".format(DEIS))
     opt = child.expect(['Import EC2 credentials\? \(y/n\) :',
                        'No EC2 credentials discovered.'])
     if opt == 0: