Skip to content

Commit

Permalink
Merge pull request buildbot#7756 from p12tic/www-fix-index-resource
Browse files Browse the repository at this point in the history
www: Replace uses of old IndexResource with IndexResourceReact
  • Loading branch information
p12tic authored Jul 7, 2024
2 parents 81deab0 + 512cafb commit af0cf9e
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 211 deletions.
126 changes: 18 additions & 108 deletions master/buildbot/test/unit/www/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
import os
from unittest import mock

from parameterized import parameterized

from twisted.internet import defer
from twisted.python import log
from twisted.trial import unittest

from buildbot.test.reactor import TestReactorMixin
Expand Down Expand Up @@ -82,108 +83,7 @@ def test_render(self):
self.assertEqual(res, exp)


class IndexResource(TestReactorMixin, www.WwwTestMixin, unittest.TestCase):
def setUp(self):
self.setup_test_reactor()

@defer.inlineCallbacks
def test_render(self):
_auth = auth.NoAuth()
_auth.maybeAutoLogin = mock.Mock()

custom_versions = [['test compoent', '0.1.2'], ['test component 2', '0.2.1']]

master = self.make_master(url='h:/a/b/', auth=_auth, versions=custom_versions)
rsrc = config.IndexResource(master, "foo")
rsrc.reconfigResource(master.config)
rsrc.jinja = mock.Mock()
template = mock.Mock()
rsrc.jinja.get_template = lambda x: template
template.render = lambda configjson, config, custom_templates: configjson

vjson = [list(v) for v in config.get_environment_versions()] + custom_versions

res = yield self.render_resource(rsrc, b'/')
res = json.loads(bytes2unicode(res))
_auth.maybeAutoLogin.assert_called_with(mock.ANY)
exp = {
"authz": {},
"titleURL": "http://buildbot.net",
"versions": vjson,
"title": "Buildbot",
"auth": {"name": "NoAuth"},
"user": {"anonymous": True},
"buildbotURL": "h:/a/b/",
"multiMaster": False,
"port": None,
}
self.assertEqual(res, exp)

master.session.user_info = {"name": 'me', "email": '[email protected]'}
res = yield self.render_resource(rsrc, b'/')
res = json.loads(bytes2unicode(res))
exp = {
"authz": {},
"titleURL": "http://buildbot.net",
"versions": vjson,
"title": "Buildbot",
"auth": {"name": "NoAuth"},
"user": {"email": "[email protected]", "name": "me"},
"buildbotURL": "h:/a/b/",
"multiMaster": False,
"port": None,
}
self.assertEqual(res, exp)

master = self.make_master(url='h:/a/c/', auth=_auth, versions=custom_versions)
rsrc.reconfigResource(master.config)
res = yield self.render_resource(rsrc, b'/')
res = json.loads(bytes2unicode(res))
exp = {
"authz": {},
"titleURL": "http://buildbot.net",
"versions": vjson,
"title": "Buildbot",
"auth": {"name": "NoAuth"},
"user": {"anonymous": True},
"buildbotURL": "h:/a/b/",
"multiMaster": False,
"port": None,
}
self.assertEqual(res, exp)

def test_parseCustomTemplateDir(self):
exp = {'views/builds.html': '<div>\n</div>'}
try:
# we make the test work if pypugjs is present or note
# It is better than just skip if pypugjs is not there
import pypugjs # pylint: disable=import-outside-toplevel

[pypugjs]
exp.update({
'plugin/views/plugin.html': '<div class="myclass"><pre>this is customized</pre></div>'
})
except ImportError:
log.msg("Only testing html based template override")
template_dir = os.path.join(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'test_templates_dir'
)
master = self.make_master(url='h:/a/b/')
rsrc = config.IndexResource(master, "foo")
res = rsrc.parseCustomTemplateDir(template_dir)
self.assertEqual(res, exp)

def test_CustomTemplateDir(self):
master = self.make_master(url='h:/a/b/')
rsrc = config.IndexResource(master, "foo")
master.config.www['custom_templates_dir'] = 'foo'
rsrc.parseCustomTemplateDir = mock.Mock(return_value="returnvalue")
rsrc.reconfigResource(master.config)
self.assertNotIn('custom_templates_dir', rsrc.frontend_config)
self.assertEqual('returnvalue', rsrc.custom_templates)


class IndexResourceReactTest(TestReactorMixin, www.WwwTestMixin, unittest.TestCase):
class IndexResourceTest(TestReactorMixin, www.WwwTestMixin, unittest.TestCase):
def setUp(self):
self.setup_test_reactor()

Expand Down Expand Up @@ -216,19 +116,29 @@ def extract_config_json(self, res):
config_json = config_json.strip(';').strip()
return json.loads(config_json)

@parameterized.expand([
('anonymous_user', None, {'anonymous': True}),
(
'logged_in_user',
{"name": 'me', "email": '[email protected]'},
{"email": "[email protected]", "name": "me"},
),
])
@defer.inlineCallbacks
def test_render(self):
def test_render(self, name, user_info, expected_user):
_auth = auth.NoAuth()
_auth.maybeAutoLogin = mock.Mock()

custom_versions = [['test compoent', '0.1.2'], ['test component 2', '0.2.1']]

master = self.make_master(url='h:/a/b/', auth=_auth, versions=custom_versions, plugins={})
if user_info is not None:
master.session.user_info = user_info

# IndexResourceReact only uses static path to get index.html. In the source checkout
# IndexResource only uses static path to get index.html. In the source checkout
# index.html resides not in www/base/public but in www/base. Thus
# base path is sent to IndexResourceReact.
rsrc = config.IndexResourceReact(master, self.get_react_base_path())
# base path is sent to IndexResource.
rsrc = config.IndexResource(master, self.get_react_base_path())
rsrc.reconfigResource(master.config)

vjson = [list(v) for v in config.get_environment_versions()] + custom_versions
Expand All @@ -243,7 +153,7 @@ def test_render(self):
"versions": vjson,
"title": "Buildbot",
"auth": {"name": "NoAuth"},
"user": {"anonymous": True},
"user": expected_user,
"buildbotURL": "h:/a/b/",
"multiMaster": False,
"port": None,
Expand Down
88 changes: 0 additions & 88 deletions master/buildbot/www/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,8 @@

import json
import os
import posixpath

import jinja2
from twisted.internet import defer
from twisted.python import log
from twisted.web.error import Error

from buildbot.interfaces import IConfigured
Expand Down Expand Up @@ -144,91 +141,6 @@ class IndexResource(resource.Resource):
# enable reconfigResource calls
needsReconfig = True

def __init__(self, master, staticdir):
super().__init__(master)
loader = jinja2.FileSystemLoader(staticdir)
self.jinja = jinja2.Environment(loader=loader, undefined=jinja2.StrictUndefined)

def reconfigResource(self, new_config):
self.config = new_config.www
self.frontend_config = get_www_frontend_config_dict(self.master, self.config)

self.custom_templates = {}
template_dir = self.config.get('custom_templates_dir', None)
if template_dir is not None:
template_dir = os.path.join(self.master.basedir, template_dir)
self.custom_templates = self.parseCustomTemplateDir(template_dir)

def render_GET(self, request):
return self.asyncRenderHelper(request, self.renderIndex)

def parseCustomTemplateDir(self, template_dir):
res = {}
allowed_ext = [".html"]
try:
import pypugjs # pylint: disable=import-outside-toplevel

allowed_ext.append(".jade")
except ImportError: # pragma: no cover
log.msg(f"pypugjs not installed. Ignoring .jade files from {template_dir}")
pypugjs = None
for root, _, files in os.walk(template_dir):
if root == template_dir:
template_name = posixpath.join("views", "%s.html")
else:
# template_name is a url, so we really want '/'
# root is a os.path, though
template_name = posixpath.join(os.path.basename(root), "views", "%s.html")
for f in files:
fn = os.path.join(root, f)
basename, ext = os.path.splitext(f)
if ext not in allowed_ext:
continue
html = None
if ext == ".html":
with open(fn, encoding='utf-8') as f:
html = f.read().strip()
elif ext == ".jade":
with open(fn, encoding='utf-8') as f:
jade = f.read()
parser = pypugjs.parser.Parser(jade)
block = parser.parse()
compiler = pypugjs.ext.html.Compiler(block, pretty=False)
html = compiler.compile()
res[template_name % (basename,)] = html

return res

@defer.inlineCallbacks
def renderIndex(self, request):
config = {}
request.setHeader(b"content-type", b'text/html')
request.setHeader(b"Cache-Control", b"public,max-age=0")

try:
yield self.config['auth'].maybeAutoLogin(request)
except Error as e:
config["on_load_warning"] = e.message

config.update(self.frontend_config)
config.update({"user": self.master.www.getUserInfos(request)})

tpl = self.jinja.get_template('index.html')
# we use Jinja in order to render some server side dynamic stuff
# For example, custom_templates javascript is generated by the
# layout.jade jinja template
tpl = tpl.render(
configjson=serialize_www_frontend_config_dict_to_json(config),
custom_templates=self.custom_templates,
config=self.config,
)
return unicode2bytes(tpl, encoding='ascii')


class IndexResourceReact(resource.Resource):
# enable reconfigResource calls
needsReconfig = True

def __init__(self, master, staticdir):
super().__init__(master)
self.static_dir = staticdir
Expand Down
18 changes: 4 additions & 14 deletions master/buildbot/www/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,20 +321,10 @@ def setupSite(self, new_config):
root = self.apps.get(self.base_plugin_name).resource
self.configPlugins(root, new_config)
# /
if self.base_plugin_name == 'base':
root.putChild(
b'',
wwwconfig.IndexResource(
self.master, self.apps.get(self.base_plugin_name).static_dir
),
)
else:
root.putChild(
b'',
wwwconfig.IndexResourceReact(
self.master, self.apps.get(self.base_plugin_name).static_dir
),
)
root.putChild(
b'',
wwwconfig.IndexResource(self.master, self.apps.get(self.base_plugin_name).static_dir),
)

# /auth
root.putChild(b'auth', auth.AuthRootResource(self.master))
Expand Down
1 change: 1 addition & 0 deletions master/docs/spelling_wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,7 @@ tgrid
tgz
tls
th
theming
timestamp
Todo
tokenUri
Expand Down
1 change: 1 addition & 0 deletions newsfragments/www-fix-broken-theming.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix broken theming in web frontend when not using it via `base_react` plugin name.
2 changes: 1 addition & 1 deletion requirements-ci.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
-e worker
-e pkg
# we install buildbot www from pypi to avoid the slow nodejs build at each test
buildbot-www==3.11.3
buildbot-www==4.0.0

autobahn==23.6.2; python_version >= "3.9"
autobahn==22.7.1; python_version < "3.9" # pyup: ignore
Expand Down

0 comments on commit af0cf9e

Please sign in to comment.