trafficserver-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jpe...@apache.org
Subject [2/6] trafficserver git commit: TS-3580: Add tests for cache generation IDs.
Date Mon, 15 Jun 2015 16:28:07 GMT
TS-3580: Add tests for cache generation IDs.


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/9e862d1a
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/9e862d1a
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/9e862d1a

Branch: refs/heads/master
Commit: 9e862d1ae83a75c9b7ea6fef37ff8d30e920511c
Parents: 4d7d892
Author: James Peach <jpeach@apache.org>
Authored: Mon May 11 08:51:00 2015 -0700
Committer: James Peach <jpeach@apache.org>
Committed: Mon Jun 15 09:16:00 2015 -0700

----------------------------------------------------------------------
 ci/tsqa/tests/test_cache_generation.py | 159 ++++++++++++++++++++++++++++
 1 file changed, 159 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e862d1a/ci/tsqa/tests/test_cache_generation.py
----------------------------------------------------------------------
diff --git a/ci/tsqa/tests/test_cache_generation.py b/ci/tsqa/tests/test_cache_generation.py
new file mode 100644
index 0000000..6a79485
--- /dev/null
+++ b/ci/tsqa/tests/test_cache_generation.py
@@ -0,0 +1,159 @@
+'''
+Test the cache generation configuration
+'''
+
+#  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 subprocess
+import logging
+import requests
+import random
+import uuid
+import time
+
+import helpers
+import tsqa.test_cases
+import tsqa.utils
+
+log = logging.getLogger(__name__)
+
+
+class TestCacheGeneration(helpers.EnvironmentCase):
+    '''
+    Test the cache object generation ID.
+    '''
+
+    def _fetch(self, path):
+        url = 'http://127.0.0.1:{}/{}'.format(
+                self.configs['records.config']['CONFIG']['proxy.config.http.server_ports'],
+                path
+        )
+        log.debug('get {}'.format(url))
+        return requests.get(url, headers={'x-debug': 'x-cache,x-cache-key,via,x-cache-generation'})
+
+    def _dump(self, response):
+        log.info('HTTP response {}'.format(response.status_code))
+        for k, v in response.headers.items():
+            log.info('    {}: {}'.format(k, v))
+
+    def _ctl(self, *args):
+        cmd = [os.path.join(self.environment.layout.bindir, 'traffic_ctl')] + list(args)
+        out, _ = tsqa.utils.run_sync_command(cmd,
+                env=self.environment.shell_env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
+        )
+        return out
+
+    @classmethod
+    def setUpEnv(cls, env):
+
+        cls.configs['plugin.config'].add_line('xdebug.so')
+
+        cls.configs['remap.config'].add_line(
+            'map /default/ http://127.0.0.1/ @plugin=generator.so'
+        )
+        cls.configs['remap.config'].add_line(
+            'map /generation1/ http://127.0.0.1/' +
+            ' @plugin=conf_remap.so @pparam=proxy.config.http.cache.generation=1' +
+            ' @plugin=generator.so'
+        )
+        cls.configs['remap.config'].add_line(
+            'map /generation2/ http://127.0.0.1/' +
+            ' @plugin=conf_remap.so @pparam=proxy.config.http.cache.generation=2' +
+            ' @plugin=generator.so'
+        )
+
+        # Start with cache generation turned off
+        cls.configs['records.config']['CONFIG']['proxy.config.http.cache.generation'] = -1
+        # Wait for the cache so we don't race client requests against it.
+        cls.configs['records.config']['CONFIG']['proxy.config.http.wait_for_cache'] = 1
+        cls.configs['records.config']['CONFIG']['proxy.config.config_update_interval_ms']
= 1
+
+    def test_generations_are_disjoint(self):
+        """Test that the same URL path in different cache generations creates disjoint objects"""
+        objectid = uuid.uuid4()
+
+        # First touch is a MISS.
+        ret = self._fetch('default/cache/10/{}'.format(objectid))
+        self.assertEqual(ret.status_code, 200)
+        self.assertEqual(ret.headers['x-cache'], 'miss', msg=ret)
+        self.assertEqual(ret.headers['x-cache-generation'], '-1')
+
+        # Same URL in generation 1 is a MISS.
+        ret = self._fetch('generation1/cache/10/{}'.format(objectid))
+        self.assertEqual(ret.status_code, 200)
+        self.assertEqual(ret.headers['x-cache'], 'miss')
+        self.assertEqual(ret.headers['x-cache-generation'], '1')
+
+        # Same URL in generation 2 is still a MISS.
+        ret = self._fetch('generation2/cache/10/{}'.format(objectid))
+        self.assertEqual(ret.status_code, 200)
+        self.assertEqual(ret.headers['x-cache'], 'miss')
+        self.assertEqual(ret.headers['x-cache-generation'], '2')
+
+        # Second touch is a HIT.
+        ret = self._fetch('default/cache/10/{}'.format(objectid))
+        self.assertEqual(ret.status_code, 200)
+        self.assertEqual(ret.headers['x-cache'], 'hit-fresh', msg=ret.headers['x-cache'])
+        self.assertEqual(ret.headers['x-cache-generation'], '-1')
+
+    def test_online_cache_clear(self):
+        """Test that incrementing the cache generation acts like a cache clear"""
+        objectid = uuid.uuid4()
+
+        # First touch is a MISS.
+        ret = self._fetch('default/cache/10/{}'.format(objectid))
+        self.assertEqual(ret.status_code, 200)
+        self.assertEqual(ret.headers['x-cache'], 'miss')
+
+        # Second touch is a HIT.
+        ret = self._fetch('default/cache/10/{}'.format(objectid))
+        self.assertEqual(ret.status_code, 200)
+        self.assertEqual(ret.headers['x-cache'], 'hit-fresh')
+
+        # Now update the generation number.
+        timeout = float(self._ctl('config', 'get', 'proxy.config.config_update_interval_ms').split('
')[-1])
+        generation = random.randrange(65000)
+        gencount = 0
+
+        self._ctl('config', 'set', 'proxy.config.http.cache.generation', str(generation))
+        self._ctl('config', 'reload')
+
+        for _ in xrange(5):
+            if gencount == 0:
+                log.debug('waiting {} secs for the config to update'.format(timeout / 1000))
+                time.sleep(timeout / 1000)
+
+            ret = self._fetch('default/cache/10/{}'.format(objectid))
+            self.assertEqual(ret.status_code, 200)
+
+            if ret.headers['x-cache-generation'] == str(generation):
+                if gencount == 0:
+                    # First time we see the new generation, it should be a miss.
+                    self.assertEqual(ret.headers['x-cache'], 'miss')
+                else:
+                    # Now the previous hits should become misses.
+                    self.assertEqual(ret.headers['x-cache'], 'hit-fresh')
+            else:
+                # Config has not updated, so it should be a hit.
+                self.assertEqual(ret.headers['x-cache'], 'hit-fresh')
+                self.assertEqual(ret.headers['x-cache-generation'], '-1')
+
+                gencount = gencount + 1
+
+        self.assertNotEqual(gencount, 0, msg='proxy.config.http.cache.generation never updated')
+


Mime
View raw message