Skip to content

Servlet import fix #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions webware/ImportManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,10 @@ def getReloader(self):
print()
return reloader

def moduleFromSpec(self, spec, name=None):
def moduleFromSpec(self, spec):
"""Load the module with the given module spec."""
if not spec or not isinstance(spec, ModuleSpec):
raise TypeError(f'Invalid spec: {spec!r}')
if name and not isinstance(name, str):
raise TypeError(f'Invalid name: {name!r}')
try:
module = module_from_spec(spec)
except Exception:
Expand All @@ -76,14 +74,11 @@ def moduleFromSpec(self, spec, name=None):
if spec.origin:
self.recordFile(spec.origin)
raise
if name:
spec.name = name
module.__package__ = spec.parent
self.recordModule(module)
spec.loader.exec_module(module)
return module

def findSpec(self, name, path):
def findSpec(self, name, path, fullModuleName=None):
"""Find the module spec for the given name at the given path."""
if not name or not isinstance(name, str):
raise TypeError(f'Invalid name: {name!r}')
Expand All @@ -106,6 +101,8 @@ def findSpec(self, name, path):
fileName = f'{name}.py'
filePath = join(path, fileName)
if isfile(filePath):
if fullModuleName:
name = fullModuleName
loader = SourceFileLoader(name, filePath)
return spec_from_file_location(name, filePath, loader=loader)

Expand Down
6 changes: 3 additions & 3 deletions webware/ServletFactory.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,10 @@ def _importModuleFromDirectory(
'# Auto-generated by Webware' + os.linesep)
except Exception:
print("Error: __init__.py file could not be created.")
spec = self._imp.findSpec(moduleName, directory)
module = self._imp.moduleFromSpec(spec, fullModuleName)
spec = self._imp.findSpec(moduleName, directory, fullModuleName)
module = self._imp.moduleFromSpec(spec)
module.__donotreload__ = self._reloadClasses
sys.modules['fullModuleName'] = module
sys.modules[fullModuleName] = module
return module

def loadClass(self, transaction, path):
Expand Down
26 changes: 26 additions & 0 deletions webware/Testing/ServletImport.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

from Page import Page
import sys

mod_name = __name__ # we expect Testing.ServletImport

class ServletImport(Page):
"""Test of import details."""

def title(self):
return self.__doc__

def writeBody(self):
self.writeln('<h2>Webware Servlet Import Test</h2>')
self.writeln(f'<h3>{self.title()}</h3>')
mod_name_from_class = ServletImport.__module__ # we expect Testing.ServletImport
mod_name_consistent = mod_name == mod_name_from_class # we expect True
servlet_in_sys_modules = mod_name in sys.modules # we expect True
servlet_file_watched = __file__ in self.transaction().application()._imp.fileList(update=False) # we expect True
self.writeln(
f"<p>mod_name = <code>{mod_name}</code></p>"
f"<p>mod_name_from_class = <code>{mod_name_from_class}</code></p>"
f"<p>mod_name_consistent = <code>{mod_name_consistent}</code></p>"
f"<p>servlet_in_sys_modules = <code>{servlet_in_sys_modules}</code></p>"
f"<p>servlet_file_watched = <code>{servlet_file_watched}</code></p>"
)
3 changes: 3 additions & 0 deletions webware/Testing/TestCases.data
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,6 @@

# If-Modified-Since
/Testing/TestIMS --> TestIMS passed

# ServletImport
/Testing/ServletImport --> Servlet imported as part of package
50 changes: 32 additions & 18 deletions webware/Tests/TestEndToEnd/AppTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ class AppTest:
settings = dict(
PrintConfigAtStartUp=False
)
bufferOutput = True # set to False if you want to run pdb inside a test to debug it.

@classmethod
def setUpClass(cls):
stdout, stderr = sys.stdout, sys.stderr
sys.stdout = sys.stderr = StringIO()
if cls.bufferOutput:
sys.stdout = sys.stderr = StringIO()
cls.currentDir = getcwd()
import webware
webwareDir = webware.__path__[0]
Expand All @@ -35,43 +37,55 @@ def setUpClass(cls):
else:
error = None
finally:
output = sys.stdout.getvalue().rstrip()
sys.stdout, sys.stderr = stdout, stderr
if cls.bufferOutput:
output = sys.stdout.getvalue().rstrip()
sys.stdout, sys.stderr = stdout, stderr
else:
output = ''
if error:
raise RuntimeError(
'Error setting up application:\n' + error +
'\nOutput was:\n' + output)
if (not output.startswith('Webware for Python')
or 'Running in development mode' not in output
or 'Loading context' not in output):
raise AssertionError(
'Application was not properly started.'
' Output was:\n' + output)
if cls.bufferOutput:
if (not output.startswith('Webware for Python')
or 'Running in development mode' not in output
or 'Loading context' not in output):
raise AssertionError(
'Application was not properly started.'
' Output was:\n' + output)

@classmethod
def tearDownClass(cls):
stdout, stderr = sys.stdout, sys.stderr
sys.stdout = sys.stderr = StringIO()
if cls.bufferOutput:
sys.stdout = sys.stderr = StringIO()
cls.app.shutDown()
output = sys.stdout.getvalue().rstrip()
sys.stdout, sys.stderr = stdout, stderr
if cls.bufferOutput:
output = sys.stdout.getvalue().rstrip()
sys.stdout, sys.stderr = stdout, stderr
else:
output = ''
chdir(cls.currentDir)
if output != ('Application is shutting down...\n'
'Application has been successfully shutdown.'):
if cls.bufferOutput and output != ('Application is shutting down...\n'
'Application has been successfully shutdown.'):
raise AssertionError(
'Application was not properly shut down. Output was:\n'
+ output)

def setUp(self):
self.stdout, self.stderr = sys.stdout, sys.stderr
sys.stdout = sys.stderr = StringIO()
if self.bufferOutput:
sys.stdout = sys.stderr = StringIO()

def tearDown(self):
self.output = sys.stdout.getvalue().rstrip()
sys.stdout, sys.stderr = self.stdout, self.stderr
if self.bufferOutput:
self.output = sys.stdout.getvalue().rstrip()
sys.stdout, sys.stderr = self.stdout, self.stderr
else:
self.output = ''

def run(self, result=None):
result = super().run(result) # pylint: disable=no-member
if not result.wasSuccessful() and self.output:
if not result.wasSuccessful() and self.bufferOutput and self.output:
print("Application output was:")
print(self.output)
9 changes: 8 additions & 1 deletion webware/Tests/TestEndToEnd/TestAdmin.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,14 @@ def testAppControl(self):
'Reload the selected Python modules. Be careful!',
'<input type="checkbox" name="reloads"'
' value="Admin.AdminPage"> Admin.AdminPage<br>')
r.form.get('reloads', index=0).checked = True

# things change, so don't hardcode the index of this checkbox.
for i, checkbox in enumerate(r.html.find_all('input', attrs={'name': 'reloads'})):
if checkbox.attrs['value'] == 'Admin.AdminPage':
break
else:
assert False, 'Did not find expected checkbox for Admin.AdminPage'
r.form.get('reloads', index=i).checked = True
r = r.form.submit('action', index=1)
self.assertEqual(r.status, '200 OK')
r.mustcontain(
Expand Down
10 changes: 10 additions & 0 deletions webware/Tests/TestEndToEnd/TestTesting.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,16 @@ def testCase17(self):
self.assertEqual(r.headers.get('Last-Modified'), lastMod)
self.assertEqual(len(r.body), size)

def testCase18(self):
url = self.getTestCaseUrl(18, 'Servlet imported as part of package')
r = self.testApp.get(url)
self.assertEqual(r.status, '200 OK')
r.mustcontain(
'<title>Test of import details.</title>',
'<p>mod_name = <code>Testing.ServletImport</code></p>',
'<p>mod_name_from_class = <code>Testing.ServletImport</code></p>',
f"<p>servlet_in_sys_modules = <code>True</code></p>",
)

class TestTestingWithExtraPathInfo(TestTesting):

Expand Down