<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman",serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="ES-MX" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:#1F497D;mso-fareast-language:EN-US">Yes, thanks for the heads up. I will send version 2.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:#1F497D;mso-fareast-language:EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:#1F497D;mso-fareast-language:EN-US">Humberto<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:#1F497D;mso-fareast-language:EN-US"><o:p>&nbsp;</o:p></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><a name="_____replyseparator"></a><b><span lang="EN-US" style="font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif">From:</span></b><span lang="EN-US" style="font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif"> Christopher Larson [mailto:clarson@kergoth.com]
<br>
<b>Sent:</b> Tuesday, February 16, 2016 4:20 PM<br>
<b>To:</b> Ibarra Lopez, Humberto &lt;humberto.ibarra.lopez@intel.com&gt;; openembedded-core@lists.openembedded.org<br>
<b>Subject:</b> Re: [OE-core] [PATCH 2/2] scripts/oe-selftest: Use site.USER_SITE to run coverage configuration code for sub-process<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<div>
<p class="MsoNormal">Shouldn't this use a try/finally to ensure the user's site area is properly cleaned up if coverage_report() raises an exception? I doubt you want to risk leaving that around.<o:p></o:p></p>
</div>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<div>
<div>
<p class="MsoNormal">On Tue, Feb 16, 2016 at 1:10 PM &lt;<a href="mailto:humberto.ibarra.lopez@intel.com">humberto.ibarra.lopez@intel.com</a>&gt; wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal">From: Humberto Ibarra &lt;<a href="mailto:humberto.ibarra.lopez@intel.com" target="_blank">humberto.ibarra.lopez@intel.com</a>&gt;<br>
<br>
Coverage in oe-selftest currently requires to create or modify<br>
a sitecustomize.py file according the coverage tool setup instructions<br>
(<a href="http://coverage.readthedocs.org/" target="_blank">http://coverage.readthedocs.org/</a>). This file has to be located in<br>
the system's python folder, which is not a good solution since this<br>
folder is not accesible to non-privileged users.<br>
<br>
The best solution so far is to create this file in the home directory.<br>
This is implemented by creating the temporal file in the user site<br>
default folder.<br>
<br>
[Yocto #8930]<br>
<br>
Signed-off-by: Humberto Ibarra &lt;<a href="mailto:humberto.ibarra.lopez@intel.com" target="_blank">humberto.ibarra.lopez@intel.com</a>&gt;<br>
---<br>
&nbsp;scripts/oe-selftest | 41 &#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;----------<br>
&nbsp;1 file changed, 31 insertions(&#43;), 10 deletions(-)<br>
<br>
diff --git a/scripts/oe-selftest b/scripts/oe-selftest<br>
index f3865e4..3159d22 100755<br>
--- a/scripts/oe-selftest<br>
&#43;&#43;&#43; b/scripts/oe-selftest<br>
@@ -553,6 &#43;553,7 @@ def main():<br>
<br>
&nbsp;def buildResultClass(args):<br>
&nbsp; &nbsp; &nbsp;&quot;&quot;&quot;Build a Result Class to use in the testcase execution&quot;&quot;&quot;<br>
&#43;&nbsp; &nbsp; import site<br>
<br>
&nbsp; &nbsp; &nbsp;class StampedResult(unittest.TextTestResult):<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;&quot;&quot;<br>
@@ -568,26 &#43;569,41 @@ def buildResultClass(args):<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;def startTestRun(self):<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;&quot;&quot; Setup coverage before running any testcase &quot;&quot;&quot;<br>
&#43;<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # variable holding the coverage configuration file allowing subprocess to be measured<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.coveragepth = None<br>
&#43;<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # indicates the system if coverage is currently installed<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.coverage_installed = True<br>
&#43;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if args.coverage or args.coverage_source or args.coverage_include or args.coverage_omit:<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;try:<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# check if user can do coverage<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;import coverage<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://log.info" target="_blank">log.info</a>(&quot;Coverage is enabled&quot;)<br>
-<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # In case the user has not set the variable COVERAGE_PROCESS_START,<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # create a default one and export it. The COVERAGE_PROCESS_START<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # value indicates where the coverage configuration file resides<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # More info on <a href="https://pypi.python.org/pypi/coverage" target="_blank">
https://pypi.python.org/pypi/coverage</a><br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if not os.environ.get('COVERAGE_PROCESS_START'):<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; os.environ['COVERAGE_PROCESS_START'] = coverage_setup(args.run_tests, args.run_all_tests, args.coverage_source, args.coverage_include, args.coverage_omit)<br>
-<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.coverage_installed = True<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;except:<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;log.warn('\n'.join([&quot;python coverage is not installed&quot;,<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;Make sure your coverage takes into account sub-process&quot;,<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;More info on <a href="https://pypi.python.org/pypi/coverage" target="_blank">
https://pypi.python.org/pypi/coverage</a>&quot;]))<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;self.coverage_installed = False<br>
<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if self.coverage_installed:<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://log.info" target="_blank">log.info</a>(&quot;Coverage is enabled&quot;)<br>
&#43;<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # In case the user has not set the variable COVERAGE_PROCESS_START,<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # create a default one and export it. The COVERAGE_PROCESS_START<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # value indicates where the coverage configuration file resides<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # More info on <a href="https://pypi.python.org/pypi/coverage" target="_blank">
https://pypi.python.org/pypi/coverage</a><br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if not os.environ.get('COVERAGE_PROCESS_START'):<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; os.environ['COVERAGE_PROCESS_START'] = coverage_setup(args.run_tests, args.run_all_tests, args.coverage_source, args.coverage_include, args.coverage_omit)<br>
&#43;<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Use default site.USER_SITE and write corresponding config file<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; site.ENABLE_USER_SITE = True<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if not os.path.exists(site.USER_SITE):<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; os.makedirs(site.USER_SITE)<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.coveragepth = os.path.join(site.USER_SITE, &quot;coverage.pth&quot;)<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; with open(self.coveragepth, 'w') as cps:<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cps.write('import sys,site; sys.path.extend(site.getsitepackages()); import coverage; coverage.process_startup();')<br>
&#43;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;def stopTestRun(self):<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;&quot;&quot; Report coverage data after the testcases are run &quot;&quot;&quot;<br>
<br>
@@ -601,6 &#43;617,11 @@ def buildResultClass(args):<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<a href="http://log.info" target="_blank">log.info</a>(&quot;===============&quot;)<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;coverage_report()<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # remove the pth file<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try:<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; os.remove(self.coveragepth)<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; except OSError:<br>
&#43;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pass<br>
<br>
&nbsp; &nbsp; &nbsp;return StampedResult<br>
<br>
--<br>
1.9.1<br>
<br>
--<br>
_______________________________________________<br>
Openembedded-core mailing list<br>
<a href="mailto:Openembedded-core@lists.openembedded.org" target="_blank">Openembedded-core@lists.openembedded.org</a><br>
<a href="http://lists.openembedded.org/mailman/listinfo/openembedded-core" target="_blank">http://lists.openembedded.org/mailman/listinfo/openembedded-core</a><o:p></o:p></p>
</blockquote>
</div>
</div>
</div>
</body>
</html>