test_component_reloading.py :  » Template-Engines » Myghty » Myghty-1.1 » test » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Template Engines » Myghty 
Myghty » Myghty 1.1 » test » test_component_reloading.py
# test/reload.py
"""Test that components reload properly when their source is touched.
"""
import unittest, os, shutil, stat, sys, time, warnings
from StringIO import StringIO

import testbase
from myghty.interp import Interpreter
from myghty.http.WSGIHandler import WSGIHandler
from myghty.resolver import NotFound
import myghty.importer

class ModuleRunner:
    """A minimal context for executing components.
    """
    def __init__(self, **params):
        self.interpreter = Interpreter(**params)

    def executeComponent(self, comp):
        buf = StringIO()
        self.interpreter.execute(comp, out_buffer=buf)
        return buf.getvalue()

class WSGIModuleRunner:
    """An WSGI context for executing components.

    We need this to test Routes components, since they require
    a request (r) object.
    """
    
    def __init__(self, **params):
        self.app = WSGIHandler(**params).handle
        
    def executeComponent(self, comp):
        environ = {
            'REQUEST_METHOD': 'GET',
            'SCRIPT_NAME': '',
            'PATH_INFO': comp,
            'SERVER_NAME': 'localhost',
            'SERVER_PORT': 8000,
            'SERVER_PROTOCOL': 'HTTP/1.1',
            'HTTP_HOST': 'localhost:8000',
            'wsgi.version': (1,0),
            'wsgi.url_scheme': 'http',
            'wsgi.input': StringIO(),
            'wsgi.errors': sys.stderr,
            'wsgi.multithread': False,
            'wsgi.multiprocess': False,
            'wsgi.run_once': False,
            }

        buf = StringIO()
        def start_response(status, response_headers):
            return buf.write
            
        for s in self.app(environ, start_response):
            buf.write(s)
            
        return buf.getvalue()
    
def purge_module(module_name):
    try:
        module = sys.modules[module_name]
    except KeyError:
        return

    base, ext = os.path.splitext(module.__file__)
    for ext in '.pyc', '.pyo':
        try:
            os.unlink(base + ext)
        except OSError:
            pass

    del sys.modules[module_name]
    
class ComponentReloadTests:
    """Abstract base class of tests for component reloading."""

    module_runner_class = ModuleRunner
    
    def setUp(self):
        # Blow away cache
        shutil.rmtree(os.path.join(self.cache, 'obj'),
                      ignore_errors=True)
        # Clear importer cache
        myghty.importer.modules.clear()

        self.createComponentSource()

        params = self.resolverArgs()
        self.module_runner = self.module_runner_class(data_dir=self.cache,
                                                      **params)


    def tearDown(self):
        self.removeComponentSource()

    def srcFile(self):
        """The full path the the module source file.
        """
        raise RuntimeError, "pure virtual"

    def srcText(self, text="howdy"):
        """Get the contents of the module source.

        The module, when run, will output the value of text.
        return text
        """
        raise RuntimeError, "pure virtual"

    def resolverArgs(self):
        """Get the resolver arguments to pass to the Myghty interperter.
        """
        raise RuntimeError, "pure virtual"

    def componentPath(self):
        """Get the (URL) path to the component.
        """
        raise RuntimeError, "pure virtual"

    def createComponentSource(self, text="howdy"):
        file(self.srcFile(), "w").write(self.srcText(text))

    def changeComponentSource(self, text="changed"):
        """Covertly changes the component source without changing mtime.
        """
        srcfile = self.srcFile()
        mtime = os.stat(srcfile)[stat.ST_MTIME]
        self.createComponentSource(text)
        os.utime(srcfile, (mtime, mtime))

    def removeComponentSource(self):
        os.unlink(self.srcFile())
        base, ext = os.path.splitext(self.srcFile())
        if ext == '.py':
            for ext in '.pyc', '.pyo':
                try:
                    os.unlink(base + ext)
                except OSError:
                    pass

    def executeComponent(self):
        return self.module_runner.executeComponent(self.componentPath())

    def testComponent(self, text="howdy"):
        """Test that we can resolve and execute our component.
        """
        self.failUnlessEqual(self.executeComponent(), text)

    def testReload(self):
        """Test that component gets reloaded when it is modified.
        """
        self.testComponent()
        time.sleep(1)
        self.removeComponentSource()
        self.createComponentSource(text="changed")
        self.testComponent("changed")

    def testCompileCache(self):
        """Test that component doesn't get reloaded when it is not modified.

        (Actually, tests that component doesn't get reloaded when the source
        is modified, but the source's mtime remains unchanged.)
        """
        self.testComponent()
        time.sleep(1)
        self.changeComponentSource(text="changed")
        self.testComponent()

################################################################
#
# (The actual unittest.TestCase sub-classes begin here.)
#
################################################################


class FileComponentReloadTests(ComponentReloadTests, testbase.MyghtyTest):
    
    def srcFile(self):
        return os.path.join(self.htdocs, "comp.myt")

    def srcText(self, text="howdy"):
        return text

    def resolverArgs(self):
        return {'component_root': self.htdocs}

    def componentPath(self):
        return "/comp.myt"
    
    
class ModuleComponentReloadTests(ComponentReloadTests, testbase.MyghtyTest):
    def setUp(self):
        purge_module('module')
        ComponentReloadTests.setUp(self)
        
    def srcFile(self):
        return os.path.join(self.lib, "module.py")

    def srcText(self, text="howdy"):
        return "def comp(m): m.write('%s')" % text

    def resolverArgs(self):
        try:
            del sys.modules['module']
        except KeyError:
            pass
        return {'module_components': [{'/mycomp': 'module:comp'}]}
    
    def componentPath(self):
        return "/mycomp"

class ModuleRootComponentReloadTests(ComponentReloadTests,
                                     testbase.MyghtyTest):
    def setUp(self):
        purge_module('modroot')
        ComponentReloadTests.setUp(self)

    def srcFile(self):
        return os.path.join(self.lib, "modroot.py")

    def srcText(self, text="howdy"):
        return """
class Top:
    def comp(self, m): m.write('%s')
top = Top()
""" % text

    def resolverArgs(self):
        try:
            del sys.modules['modroot']
            pass
        except KeyError:
            pass
        return {'module_root': ['modroot']}
    
    def componentPath(self):
        return "top/comp"

class WSGIModuleRootComponentReloadTests(ModuleRootComponentReloadTests):
    """Run the module_root test in a WSGI context.

    This exercised a buglet in myghty.http.HTTPHandler.py.
    """
    module_runner_class = WSGIModuleRunner



os.environ['MYGHTY_ENV'] = 'debug'   # Otherwise RoutesResolver pukes
try:
    from routes.base import Mapper

except ImportError:
    # Routes appears not to be installed
    class RoutesComponentReloadTests(unittest.TestCase):
        def testRoutesMissing(self):
            warnings.warn("Cannot import routes.base.  Skipping Routes tests.")

else:
    # Routes seems to be installed
    from myghty.ext.routeresolver import RoutesResolver

    class RoutesComponentReloadTests(ComponentReloadTests,
                                     testbase.MyghtyTest):
        module_runner_class = WSGIModuleRunner
    
        def srcFile(self):
            return os.path.join(self.lib, "routes_controller.py")

        def srcText(self, text="howdy"):
            return """
class RoutesController:
    def index(self, m, r):
        m.write('%s')
routes = RoutesController()
""" % text

        def resolverArgs(self):
            mapper = Mapper()
            mapper.connect(':controller/:action')

            routes_resolver = RoutesResolver(
                mapper=mapper,
                controller_root = self.lib)
            
            return {'resolver_strategy': [routes_resolver, NotFound()]}
    
        def componentPath(self):
            return "/routes"

class AnonymousFunctionComponentReloadTests(testbase.ComponentTester):
    def test(self):
        def mycomp(m):
            return 1
        comp1 = self.makeModuleComponent(mycomp)

        def mycomp(m):
            return 2
        comp2 = self.makeModuleComponent(mycomp)

        print comp1.component_source.id
        self.failIfEqual(comp1, comp2, "(Currently broken, expect failure.)")
        self.failUnlessEqual(self.runComponent(comp1), 1)
        self.failUnlessEqual(self.runComponent(comp2), 2)
        
if __name__ == '__main__':
    runner = unittest.TextTestRunner(verbosity=2, descriptions=False)
    unittest.main(testRunner=runner)
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.