Commit 07a18130 authored by Jérome Perrin's avatar Jérome Perrin

slaprunner: fix popen on python3

On python3 several views were not functional, because subprocess output was
retrieved as bytes, but manipulated as a string.

This adds a few tests for views, not complete because it would be too much time
consuming for now.
parent c284b919
Pipeline #15012 passed with stage
...@@ -15,6 +15,7 @@ class Popen(subprocess.Popen): ...@@ -15,6 +15,7 @@ class Popen(subprocess.Popen):
self.name = kwargs.pop('name', None) self.name = kwargs.pop('name', None)
kwargs['stdin'] = subprocess.PIPE kwargs['stdin'] = subprocess.PIPE
kwargs['stderr'] = subprocess.STDOUT kwargs['stderr'] = subprocess.STDOUT
kwargs.setdefault('universal_newlines', True)
kwargs.setdefault('stdout', subprocess.PIPE) kwargs.setdefault('stdout', subprocess.PIPE)
kwargs.setdefault('close_fds', True) kwargs.setdefault('close_fds', True)
subprocess.Popen.__init__(self, *args, **kwargs) subprocess.Popen.__init__(self, *args, **kwargs)
......
import mock import json
import os import os
import string
import random import random
import supervisor import shutil
import string
import sys
import tempfile
import textwrap
import unittest import unittest
import mock
import slapos.runner.utils as runner_utils import slapos.runner.utils as runner_utils
import slapos.runner.views
import sys import supervisor
sys.modules['slapos.runner.utils'].sup_process = mock.MagicMock() sys.modules['slapos.runner.utils'].sup_process = mock.MagicMock()
...@@ -364,6 +368,140 @@ class TestRunnerBackEnd(unittest.TestCase): ...@@ -364,6 +368,140 @@ class TestRunnerBackEnd(unittest.TestCase):
raise NotImplementedError raise NotImplementedError
class TestViews(unittest.TestCase):
def setUp(self):
app = slapos.runner.views.app
self.client = app.test_client()
for key in (
'etc_dir',
'workspace',
'software_link',
'instance_profile',
'instance_root',
):
tmpdir = tempfile.mkdtemp()
app.config[key] = tmpdir
self.addCleanup(shutil.rmtree, tmpdir)
slapos_command_dir = tempfile.mkdtemp()
self.addCleanup(shutil.rmtree, slapos_command_dir)
slapos_command = os.path.join(slapos_command_dir, 'slapos')
self.slapos_command_arguments = os.path.join(slapos_command_dir, 'slapos.arguments')
self.slapos_command_output = os.path.join(slapos_command_dir, 'slapos.output')
with open(slapos_command, 'w') as f:
f.write(textwrap.dedent('''\
#!/bin/sh
echo $@ > {self.slapos_command_arguments}
cat {self.slapos_command_output}
'''.format(**locals())))
os.chmod(slapos_command, 0o700)
app.config['slapos'] = slapos_command
app.config['configuration_file_path'] = 'slapos.cfg'
app.config['instance_monitoring_url'] = 'https://monitoring.example.com'
app.config['master_url'] = 'https://slapos.example.com'
app.config['computer_id'] = 'COMP-1234'
app.config['partition_amount'] = 1
app.config['software_profile'] = 'https://example.com/software.cfg'
app.config['TESTING'] = True
app.secret_key = 'secret'
def test_home(self):
self.assertIn(b'SlapOS web runner', self.client.get('/').data)
def test_browseWorkspace(self):
self.assertEqual(self.client.get('/browseWorkspace').status_code, 200)
def test_editSoftwareProfile(self):
self.assertEqual(self.client.get('/editSoftwareProfile').status_code, 200)
def test_inspectSoftware(self):
self.assertEqual(self.client.get('/inspectSoftware').status_code, 200)
def test_editInstanceProfile(self):
self.assertEqual(self.client.get('/editInstanceProfile').status_code, 200)
@mock.patch('slapos.runner.utils.slapos.slap')
def test_inspectInstance(self, _slap):
with open(self.slapos_command_output, 'w') as f:
f.write(textwrap.dedent('''
slappart1:service RUNNING pid 1234, uptime 6 days, 4:02:18
watchdog RUNNING pid 5678, uptime 6 days, 4:03:07
'''))
self.assertEqual(
json.loads(
self.client.get(
'/inspectInstance',
headers={
'Accept': 'application/json'
},
).data),
[{
'service_name':
'slappart1:service',
'status': 'RUNNING'
}],
)
with open(self.slapos_command_arguments) as f:
self.assertEqual(f.read().strip(), 'node supervisorctl --cfg slapos.cfg status')
self.assertIn(
b'<a href="/startStopProccess/name/slappart1:service/cmd/RUNNING">RUNNING</a>',
self.client.get('/inspectInstance', headers={
'Accept': '*/*'
}).data)
_slap.slap().initializeConnection.assert_called_with('https://slapos.example.com')
_slap.slap().registerComputer.assert_called_with('COMP-1234')
def test_supervisordStatus(self):
with open(self.slapos_command_output, 'w') as f:
f.write(
textwrap.dedent('''
slappart1:service RUNNING pid 1234, uptime 6 days, 4:02:18
watchdog RUNNING pid 5678, uptime 6 days, 4:03:07
'''))
self.assertEqual(
json.loads(self.client.get('/supervisordStatus').data), {
'code':
1,
'result':
"<tr><th>Partition and Process name</th><th>Status</th>"
"<th>Process PID </th><th> UpTime</th><th></th></tr><tr>"
"<td class='first'><b>"
"<a href='/tailProcess/name/slappart1:service'>slappart1:service</a>"
"</b></td><td align='center'>"
"<a href='/startStopProccess/name/slappart1:service/cmd/RUNNING'>"
"RUNNING</a></td><td align='center'>1234</td><td>6</td><td align='center'>"
"<a href='/startStopProccess/name/slappart1:service/cmd/RESTART'>"
"Restart</a></td></tr>"
})
def test_runInstanceProfile(self):
  • BTW, all these tests do not run, because of the wrong indentation; they are not class methods, but they are functions inside the method. This was something the work of running pylint on slapos repositories uncovered.

    I remember trying to de-indent so that they become test methods, and I think they were failing.

    The web interface on slaprunner is probably not fully functional either.

    ( /cc @tomo )

Please register or sign in to reply
self.assertEqual(self.client.get('/runInstanceProfile').status_code, 200)
self.assertEqual(self.client.post('/runInstanceProfile').status_code, 200)
def test_removeInstance(self):
self.assertEqual(self.client.get('/removeInstance').status_code, 200)
def test_viewLog(self):
self.assertEqual(self.client.get('/viewLog').status_code, 200)
def test_getFileLog(self):
self.assertEqual(self.client.post('/getFileLog').status_code, 200)
def test_stopAllPartition(self):
self.assertEqual(self.client.post('/stopAllPartition').status_code, 302)
def test_tailProcess(self):
self.assertEqual(
self.client.post('/tailProcess/name/slappart1:service').status_code,
200)
# TODO: test other important views
if __name__ == '__main__': if __name__ == '__main__':
random.seed() random.seed()
unittest.main() unittest.main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment