summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2018-11-16 09:33:28 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2018-11-16 11:46:07 +0000
commit11340de05b7a94583b7f1a5b4916001ea213b402 (patch)
tree3ca49f26f52e240237515fa88ebd3e0bc319cb52 /meta
parent99f0e68973e078d1d0030741435b51ccbe759ef5 (diff)
downloadpoky-11340de05b7a94583b7f1a5b4916001ea213b402.tar.gz
oeqa/utils/httpserver: Rework to avoid hangs and improve logging
testimage.bbclass installs a SIGTERM handler which conflicts with the use of multiprocessing here. This is paritcularly problematic if the http service is terminated before its started and hence before its had a chance to reset the default signal handler (as the code was written). Instead, temporarily remove testimage's handler whilst forking the http process which means the correct handler is installed and won't deadlock. Also take the opportunity to add in some log messages about the server start and shutdown so that future debugging is easier and its clearer what the code is doing. (From OE-Core rev: 0762b6021b87ceb1f37952f3a6d64a36e99ae6a5) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
-rw-r--r--meta/lib/oeqa/runtime/cases/apt.py2
-rw-r--r--meta/lib/oeqa/runtime/cases/dnf.py2
-rw-r--r--meta/lib/oeqa/runtime/cases/opkg.py2
-rw-r--r--meta/lib/oeqa/utils/httpserver.py37
4 files changed, 32 insertions, 11 deletions
diff --git a/meta/lib/oeqa/runtime/cases/apt.py b/meta/lib/oeqa/runtime/cases/apt.py
index 8d4dd35c57..793143f72c 100644
--- a/meta/lib/oeqa/runtime/cases/apt.py
+++ b/meta/lib/oeqa/runtime/cases/apt.py
@@ -18,7 +18,7 @@ class AptRepoTest(AptTest):
18 @classmethod 18 @classmethod
19 def setUpClass(cls): 19 def setUpClass(cls):
20 service_repo = os.path.join(cls.tc.td['DEPLOY_DIR_DEB'], 'all') 20 service_repo = os.path.join(cls.tc.td['DEPLOY_DIR_DEB'], 'all')
21 cls.repo_server = HTTPService(service_repo, cls.tc.target.server_ip) 21 cls.repo_server = HTTPService(service_repo, cls.tc.target.server_ip, logger=cls.tc.logger)
22 cls.repo_server.start() 22 cls.repo_server.start()
23 23
24 @classmethod 24 @classmethod
diff --git a/meta/lib/oeqa/runtime/cases/dnf.py b/meta/lib/oeqa/runtime/cases/dnf.py
index e93a1cea06..c1ed39d776 100644
--- a/meta/lib/oeqa/runtime/cases/dnf.py
+++ b/meta/lib/oeqa/runtime/cases/dnf.py
@@ -55,7 +55,7 @@ class DnfRepoTest(DnfTest):
55 @classmethod 55 @classmethod
56 def setUpClass(cls): 56 def setUpClass(cls):
57 cls.repo_server = HTTPService(os.path.join(cls.tc.td['WORKDIR'], 'oe-testimage-repo'), 57 cls.repo_server = HTTPService(os.path.join(cls.tc.td['WORKDIR'], 'oe-testimage-repo'),
58 cls.tc.target.server_ip) 58 cls.tc.target.server_ip, logger=cls.tc.logger)
59 cls.repo_server.start() 59 cls.repo_server.start()
60 60
61 @classmethod 61 @classmethod
diff --git a/meta/lib/oeqa/runtime/cases/opkg.py b/meta/lib/oeqa/runtime/cases/opkg.py
index 3be480a672..693f5d68c9 100644
--- a/meta/lib/oeqa/runtime/cases/opkg.py
+++ b/meta/lib/oeqa/runtime/cases/opkg.py
@@ -21,7 +21,7 @@ class OpkgRepoTest(OpkgTest):
21 if cls.tc.td["MULTILIB_VARIANTS"]: 21 if cls.tc.td["MULTILIB_VARIANTS"]:
22 allarchfeed = cls.tc.td["TUNE_PKGARCH"] 22 allarchfeed = cls.tc.td["TUNE_PKGARCH"]
23 service_repo = os.path.join(cls.tc.td['DEPLOY_DIR_IPK'], allarchfeed) 23 service_repo = os.path.join(cls.tc.td['DEPLOY_DIR_IPK'], allarchfeed)
24 cls.repo_server = HTTPService(service_repo, cls.tc.target.server_ip) 24 cls.repo_server = HTTPService(service_repo, cls.tc.target.server_ip, logger=cls.tc.logger)
25 cls.repo_server.start() 25 cls.repo_server.start()
26 26
27 @classmethod 27 @classmethod
diff --git a/meta/lib/oeqa/utils/httpserver.py b/meta/lib/oeqa/utils/httpserver.py
index 7d12331453..a48d4994fd 100644
--- a/meta/lib/oeqa/utils/httpserver.py
+++ b/meta/lib/oeqa/utils/httpserver.py
@@ -1,13 +1,13 @@
1import http.server 1import http.server
2import multiprocessing 2import multiprocessing
3import os 3import os
4import traceback
5import signal
4from socketserver import ThreadingMixIn 6from socketserver import ThreadingMixIn
5 7
6class HTTPServer(ThreadingMixIn, http.server.HTTPServer): 8class HTTPServer(ThreadingMixIn, http.server.HTTPServer):
7 9
8 def server_start(self, root_dir): 10 def server_start(self, root_dir, logger):
9 import signal
10 signal.signal(signal.SIGTERM, signal.SIG_DFL)
11 os.chdir(root_dir) 11 os.chdir(root_dir)
12 self.serve_forever() 12 self.serve_forever()
13 13
@@ -18,19 +18,40 @@ class HTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
18 18
19class HTTPService(object): 19class HTTPService(object):
20 20
21 def __init__(self, root_dir, host=''): 21 def __init__(self, root_dir, host='', logger=None):
22 self.root_dir = root_dir 22 self.root_dir = root_dir
23 self.host = host 23 self.host = host
24 self.port = 0 24 self.port = 0
25 self.logger = logger
25 26
26 def start(self): 27 def start(self):
28 if not os.path.exists(self.root_dir):
29 self.logger.info("Not starting HTTPService for directory %s which doesn't exist" % (self.root_dir))
30 return
31
27 self.server = HTTPServer((self.host, self.port), HTTPRequestHandler) 32 self.server = HTTPServer((self.host, self.port), HTTPRequestHandler)
28 if self.port == 0: 33 if self.port == 0:
29 self.port = self.server.server_port 34 self.port = self.server.server_port
30 self.process = multiprocessing.Process(target=self.server.server_start, args=[self.root_dir]) 35 self.process = multiprocessing.Process(target=self.server.server_start, args=[self.root_dir, self.logger])
36
37 # The signal handler from testimage.bbclass can cause deadlocks here
38 # if the HTTPServer is terminated before it can restore the standard
39 #signal behaviour
40 orig = signal.getsignal(signal.SIGTERM)
41 signal.signal(signal.SIGTERM, signal.SIG_DFL)
31 self.process.start() 42 self.process.start()
43 signal.signal(signal.SIGTERM, orig)
44
45 if self.logger:
46 self.logger.info("Started HTTPService on %s:%s" % (self.host, self.port))
47
32 48
33 def stop(self): 49 def stop(self):
34 self.server.server_close() 50 if hasattr(self, "server"):
35 self.process.terminate() 51 self.server.server_close()
36 self.process.join() 52 if hasattr(self, "process"):
53 self.process.terminate()
54 self.process.join()
55 if self.logger:
56 self.logger.info("Stopped HTTPService on %s:%s" % (self.host, self.port))
57