You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by ja...@apache.org on 2016/11/02 16:44:42 UTC

[trafficserver-qa] branch master updated (ba4179b -> 7e99eb3)

This is an automated email from the ASF dual-hosted git repository.

jacksontj pushed a change to branch master
in repository https://git-dual.apache.org/repos/asf/trafficserver-qa.git.

      from  ba4179b   Remove whitespace.
       new  0ee5683   Code formatting (for ease of reading)
       new  28770e1   Add support for `features` within traffic_layout
       new  4da5042   Refactor of test_cases to split EnvironmentFactory out of the base class
       new  7e99eb3   Add example case using feature_requirements

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "adds" were already present in the repository and have only
been added to this reference.


Summary of changes:
 examples/environment_cases.py | 12 +++++--
 tsqa/environment.py           | 56 +++++++++++++++++++----------
 tsqa/test_cases.py            | 82 +++++++++++++++++++++++++++++++++----------
 3 files changed, 109 insertions(+), 41 deletions(-)

-- 
To stop receiving notification emails like this one, please contact
['"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>'].

[trafficserver-qa] 02/04: Add support for `features` within traffic_layout

Posted by ja...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

jacksontj pushed a commit to branch master
in repository https://git-dual.apache.org/repos/asf/trafficserver-qa.git

commit 28770e1a9865458489a1fad9d4f5b9f1429cd703
Author: Thomas Jackson <ja...@gmail.com>
AuthorDate: Tue Nov 1 08:34:54 2016 -0700

    Add support for `features` within traffic_layout
    
    traffic_layout now supports returning the features it was built with as a
    JSON string. We can now expose that as a method on the environment so
    users can check against the capabilities of the build before testing
---
 tsqa/environment.py | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/tsqa/environment.py b/tsqa/environment.py
index 1fa2453..1216844 100644
--- a/tsqa/environment.py
+++ b/tsqa/environment.py
@@ -24,6 +24,7 @@ import sys
 import time
 import multiprocessing
 import hashlib
+import json
 
 import tsqa.configs
 import tsqa.utils
@@ -272,6 +273,13 @@ class Environment(object):
     cause failures in other environments.
 
     '''
+    def features(self):
+        out = subprocess.check_output([
+            os.path.join(self.layout.bindir, 'traffic_layout'),
+            '-fj',
+        ])
+        return json.loads(out.decode("utf-8"))
+
     @property
     def shell_env(self):
         environ = copy.copy(os.environ)
@@ -349,6 +357,7 @@ class Environment(object):
             os.makedirs(self.layout.prefix)
         os.chmod(self.layout.prefix, 0777)  # Make the tmp dir readable by all
 
+        # TODO: handle sock files (copytree doesn't like them!)
         # copy all files from old layout to new one
         for item in os.listdir(layout.prefix):
             src_path = os.path.join(layout.prefix, item)
@@ -395,9 +404,14 @@ class Environment(object):
             ('127.0.0.1', admin_port),
         ]
 
+        # TODO: clear out all configs!
+        # truncate remap.config
+        open(os.path.join(self.layout.sysconfdir, 'remap.config'), 'w').truncate()
+        open(os.path.join(self.layout.sysconfdir, 'records.config'), 'w').truncate()
+
         # overwrite a few things that need to be changed to have a unique env
         records = tsqa.configs.RecordsConfig(os.path.join(self.layout.sysconfdir, 'records.config'))
-        records['CONFIG'].update({
+        records['CONFIG'] = {
             'proxy.config.config_dir': self.layout.sysconfdir,
             'proxy.config.body_factory.template_sets_dir': os.path.join(self.layout.sysconfdir, 'body_factory'),
             'proxy.config.plugin.plugin_dir': self.layout.plugindir,
@@ -425,7 +439,7 @@ class Environment(object):
             # set the process_server timeouts to 0 (faster startup)
             'proxy.config.lm.pserver_timeout_secs': 0,
             'proxy.config.lm.pserver_timeout_msecs': 0,
-        })
+        }
         records.write()
 
         os.chmod(os.path.join(os.path.dirname(self.layout.runtimedir)), 0777)

-- 
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.

[trafficserver-qa] 01/04: Code formatting (for ease of reading)

Posted by ja...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

jacksontj pushed a commit to branch master
in repository https://git-dual.apache.org/repos/asf/trafficserver-qa.git

commit 0ee56836edbcc7e7f8d4ce70b5c91b5158768338
Author: Thomas Jackson <ja...@gmail.com>
AuthorDate: Mon Oct 31 21:13:21 2016 -0700

    Code formatting (for ease of reading)
---
 tsqa/environment.py | 38 +++++++++++++++++++++-----------------
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/tsqa/environment.py b/tsqa/environment.py
index c356949..1fa2453 100644
--- a/tsqa/environment.py
+++ b/tsqa/environment.py
@@ -293,11 +293,12 @@ class Environment(object):
         cmd = [path, '--debug', '--stdout']
 
         with open(os.path.join(self.layout.logdir, 'cop.log'), 'w+') as logfile:
-            self.cop = subprocess.Popen(cmd,
-                                        env=self.shell_env,
-                                        stdout=logfile,
-                                        stderr=logfile,
-                                        )
+            self.cop = subprocess.Popen(
+                cmd,
+                env=self.shell_env,
+                stdout=logfile,
+                stderr=logfile,
+            )
             start = time.time()
             # TODO: more specific exception?
             try:
@@ -356,20 +357,22 @@ class Environment(object):
             if item == layout.suffixes['bindir']:
                 os.makedirs(dst_path)  # make the dest dir
                 for bin_item in os.listdir(src_path):
-                     os.symlink(os.path.join(src_path, bin_item),
-                                os.path.join(dst_path, bin_item),
-                                )
+                     os.symlink(
+                        os.path.join(src_path, bin_item),
+                        os.path.join(dst_path, bin_item),
+                     )
 
             elif os.path.islink(src_path):
                 linkto = os.readlink(src_path)
                 os.symlink(linkto, dst_path)
 
             elif os.path.isdir(src_path):
-                shutil.copytree(src_path,
-                                dst_path,
-                                symlinks=True,
-                                ignore=None,
-                                )
+                shutil.copytree(
+                    src_path,
+                    dst_path,
+                    symlinks=True,
+                    ignore=None,
+                )
 
             elif os.path.isfile(src_path):
                 shutil.copyfile(src_path, dst_path)
@@ -386,10 +389,11 @@ class Environment(object):
         manager_mgmt_port = tsqa.utils.bind_unused_port()[1]
         admin_port = tsqa.utils.bind_unused_port()[1]
 
-        self.hostports = [('127.0.0.1', http_server_port),
-                          ('127.0.0.1', manager_mgmt_port),
-                          ('127.0.0.1', admin_port),
-                          ]
+        self.hostports = [
+            ('127.0.0.1', http_server_port),
+            ('127.0.0.1', manager_mgmt_port),
+            ('127.0.0.1', admin_port),
+        ]
 
         # overwrite a few things that need to be changed to have a unique env
         records = tsqa.configs.RecordsConfig(os.path.join(self.layout.sysconfdir, 'records.config'))

-- 
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.

[trafficserver-qa] 04/04: Add example case using feature_requirements

Posted by ja...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

jacksontj pushed a commit to branch master
in repository https://git-dual.apache.org/repos/asf/trafficserver-qa.git

commit 7e99eb3802d052d7eca87b3b9fb94f9008dc940b
Author: Thomas Jackson <ja...@gmail.com>
AuthorDate: Tue Nov 1 08:39:46 2016 -0700

    Add example case using feature_requirements
---
 examples/environment_cases.py | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/examples/environment_cases.py b/examples/environment_cases.py
index 6f202f6..d119959 100644
--- a/examples/environment_cases.py
+++ b/examples/environment_cases.py
@@ -51,6 +51,15 @@ class OverrideConfigureFlags(tsqa.test_cases.EnvironmentCase):
     }
 
 
+class FeatureRequirement(tsqa.test_cases.CloneEnvironmentCase):
+    '''
+    CloneEnvironmentCase will clone an environment (instead of building). You can
+    declare dependencies on various features in trafficserver based on the output
+    from traffic_layout. If the requirements aren't met your test will be skipped
+    '''
+    feature_requirements = {'TS_HAS_WCCP': 0}
+
+
 class ConfiguredCase(tsqa.test_cases.EnvironmentCase):
     '''
     This is the trivial example of a TestCase. The parent class (in this case
@@ -75,6 +84,3 @@ class ConfiguredCase(tsqa.test_cases.EnvironmentCase):
             'proxy.config.log.squid_log_enabled': 1,
             'proxy.config.log.squid_log_is_ascii': 1,
         })
-
-
-

-- 
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.

[trafficserver-qa] 03/04: Refactor of test_cases to split EnvironmentFactory out of the base class

Posted by ja...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

jacksontj pushed a commit to branch master
in repository https://git-dual.apache.org/repos/asf/trafficserver-qa.git

commit 4da5042ee25a0a5033b1418ae46cb3d3dbf1ed65
Author: Thomas Jackson <ja...@gmail.com>
AuthorDate: Tue Nov 1 08:31:47 2016 -0700

    Refactor of test_cases to split EnvironmentFactory out of the base class
    
    Now that we have the pieces in place to support introspection into ATS there is no need to build ATS for each test run (which is a HUGE perf gain). So instead of breaking compatability I'm refactoring the test_cases to have a shared base class and then one for EnvironmentFactory (for backwards compat) and one for CloneEnvironmentCase (which will be the new default)
---
 tsqa/test_cases.py | 82 +++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 63 insertions(+), 19 deletions(-)

diff --git a/tsqa/test_cases.py b/tsqa/test_cases.py
index bd96b2f..3849d6a 100644
--- a/tsqa/test_cases.py
+++ b/tsqa/test_cases.py
@@ -30,22 +30,16 @@ import tsqa.utils
 unittest = tsqa.utils.import_unittest()
 
 
-
-# Base environment case
-class EnvironmentCase(unittest.TestCase):
+class BaseEnvironmentCase(unittest.TestCase):
     '''
     This class will:
         - get a unique environment (using getEnv())
+        - verify that the env is valid for the test (using verifyEnv())
         - create wrappers for ATS configs available in self.configs
         - setup the environment (setUpEnv())
         - write out the configs
         - start the environment (environment.start())
     '''
-    # TODO: better naming??
-    environment_factory = {'configure': None,
-                           'env': None,
-                           }
-
     def run(self, result=None):
         unittest.TestCase.run(self, result)
         # we want to keep track of failures at a class level-- not instance level
@@ -54,13 +48,14 @@ class EnvironmentCase(unittest.TestCase):
     @classmethod
     def setUpClass(cls):
         # call parent constructor
-        super(EnvironmentCase, cls).setUpClass()
+        super(BaseEnvironmentCase, cls).setUpClass()
 
         # get a logger
         cls.log = logging.getLogger(__name__)
 
         # get an environment
         cls.environment = cls.getEnv()
+        cls.verifyEnv()
         # TODO: better... I dont think this output is captured in each test run
         logging.info('Environment prefix is {0}'.format(cls.environment.layout.prefix))
 
@@ -89,15 +84,12 @@ class EnvironmentCase(unittest.TestCase):
         cls.__successful = True
 
     @classmethod
+    def verifyEnv(cls):
+        pass
+
+    @classmethod
     def getEnv(cls):
-        '''
-        This function is responsible for returning an environment. The default
-        is to build ATS and return a copy of an environment
-        '''
-        SOURCE_DIR = os.getenv('TSQA_SRC_DIR', '~/trafficserver')
-        TMP_DIR = os.getenv('TSQA_TMP_DIR','/tmp/tsqa')
-        ef = tsqa.environment.EnvironmentFactory(SOURCE_DIR, os.path.join(TMP_DIR, 'base_envs'))
-        return ef.get_environment(cls.environment_factory['configure'], cls.environment_factory['env'])
+        raise NotImplementedError()
 
     @classmethod
     def setUpEnv(cls, env):
@@ -115,7 +107,7 @@ class EnvironmentCase(unittest.TestCase):
         cls.environment.stop()
 
         # call parent destructor
-        super(EnvironmentCase, cls).tearDownClass()
+        super(BaseEnvironmentCase, cls).tearDownClass()
         # if the test was successful, tear down the env
         if cls.__successful:
             cls.environment.destroy()  # this will tear down any processes that we started
@@ -130,6 +122,59 @@ class EnvironmentCase(unittest.TestCase):
         return {'http': 'http://127.0.0.1:{0}'.format(self.configs['records.config']['CONFIG']['proxy.config.http.server_ports'])}
 
 
+class EnvironmentFactoryCase(BaseEnvironmentCase):
+    '''TestCase that can build its own trafficserver using EnvironmentFactory
+    '''
+    # TODO: better naming??
+    environment_factory = {'configure': None,
+                           'env': None,
+                           }
+    @classmethod
+    def getEnv(cls):
+        '''
+        This function is responsible for returning an environment. The default
+        is to build ATS and return a copy of an environment
+        '''
+        SOURCE_DIR = os.getenv('TSQA_SRC_DIR', '~/trafficserver')
+        TMP_DIR = os.getenv('TSQA_TMP_DIR','/tmp/tsqa')
+        ef = tsqa.environment.EnvironmentFactory(SOURCE_DIR, os.path.join(TMP_DIR, 'base_envs'))
+        return ef.get_environment(cls.environment_factory['configure'], cls.environment_factory['env'])
+
+
+# TODO: deprecation warning? The naming for this should really be the alternate
+class EnvironmentCase(EnvironmentFactoryCase):
+    pass
+
+
+class CloneEnvironmentCase(BaseEnvironmentCase):
+    # dict of k/v that must exist in the feature list of traffic_layout
+    feature_requirements = {}
+
+    @classmethod
+    def verifyEnv(cls):
+        # verify that features requirements are met
+        env_features = cls.environment.features()
+        for k, v in cls.feature_requirements.iteritems():
+            if k not in env_features or env_features[k] != v:
+                # TODO: better error
+                raise unittest.SkipTest(e)
+
+    @classmethod
+    def getEnv(cls):
+        '''Clone an existing environment at `TSQA_ATS_ROOT`
+        '''
+        # TODO: better default? Or no default?
+        # create a layout
+        layout = tsqa.environment.Layout(
+            os.path.expanduser(os.getenv('TSQA_ATS_ROOT'))
+        )
+
+        # return an environment cloned from that layout
+        ret = tsqa.environment.Environment()
+        ret.clone(layout=layout)
+        return ret
+
+
 class DynamicHTTPEndpointCase(unittest.TestCase):
     '''
     This class will set up a dynamic http endpoint that is local to this class
@@ -187,4 +232,3 @@ class HTTPBinCase(unittest.TestCase):
             path = '/' + path
         return 'http://127.0.0.1:{0}{1}'.format(self.http_endpoint.address[1],
                                                 path)
-

-- 
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.