369
369
<a name="L207"></a><tt class="py-lineno">207</tt> <tt class="py-line"> <tt class="py-name">tmpdir</tt> <tt class="py-op">=</tt> <tt id="link-16" class="py-name"><a title="CedarBackup2.util.encodePath" class="py-name" href="#" onclick="return doclink('link-16', 'encodePath', 'link-3');">encodePath</a></tt><tt class="py-op">(</tt><tt class="py-name">tmpdir</tt><tt class="py-op">)</tt> </tt>
370
370
<a name="L208"></a><tt class="py-lineno">208</tt> <tt class="py-line"> <tt class="py-name">filepath</tt> <tt class="py-op">=</tt> <tt id="link-17" class="py-name"><a title="CedarBackup2.util.encodePath" class="py-name" href="#" onclick="return doclink('link-17', 'encodePath', 'link-3');">encodePath</a></tt><tt class="py-op">(</tt><tt class="py-name">filepath</tt><tt class="py-op">)</tt> </tt>
371
371
<a name="L209"></a><tt class="py-lineno">209</tt> <tt class="py-line"> <tt class="py-name">tar</tt> <tt class="py-op">=</tt> <tt class="py-name">tarfile</tt><tt class="py-op">.</tt><tt class="py-name">open</tt><tt class="py-op">(</tt><tt class="py-name">filepath</tt><tt class="py-op">)</tt> </tt>
372
<a name="L210"></a><tt class="py-lineno">210</tt> <tt class="py-line"> <tt class="py-name">tar</tt><tt class="py-op">.</tt><tt class="py-name">posix</tt> <tt class="py-op">=</tt> <tt class="py-name">False</tt> </tt>
373
<a name="L211"></a><tt class="py-lineno">211</tt> <tt class="py-line"> <tt class="py-keyword">for</tt> <tt class="py-name">tarinfo</tt> <tt class="py-keyword">in</tt> <tt class="py-name">tar</tt><tt class="py-op">:</tt> </tt>
374
<a name="L212"></a><tt class="py-lineno">212</tt> <tt class="py-line"> <tt class="py-name">tar</tt><tt class="py-op">.</tt><tt class="py-name">extract</tt><tt class="py-op">(</tt><tt class="py-name">tarinfo</tt><tt class="py-op">,</tt> <tt class="py-name">tmpdir</tt><tt class="py-op">)</tt> </tt>
375
</div><a name="L213"></a><tt class="py-lineno">213</tt> <tt class="py-line"> </tt>
376
<a name="L214"></a><tt class="py-lineno">214</tt> <tt class="py-line"> </tt>
377
<a name="L215"></a><tt class="py-lineno">215</tt> <tt class="py-line"><tt class="py-comment">###########################</tt> </tt>
378
<a name="L216"></a><tt class="py-lineno">216</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># changeFileAge() function</tt> </tt>
379
<a name="L217"></a><tt class="py-lineno">217</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">###########################</tt> </tt>
380
<a name="L218"></a><tt class="py-lineno">218</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
381
<a name="changeFileAge"></a><div id="changeFileAge-def"><a name="L219"></a><tt class="py-lineno">219</tt> <a class="py-toggle" href="#" id="changeFileAge-toggle" onclick="return toggle('changeFileAge');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#changeFileAge">changeFileAge</a><tt class="py-op">(</tt><tt class="py-param">filename</tt><tt class="py-op">,</tt> <tt class="py-param">subtract</tt><tt class="py-op">=</tt><tt class="py-name">None</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
382
</div><div id="changeFileAge-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="changeFileAge-expanded"><a name="L220"></a><tt class="py-lineno">220</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
383
<a name="L221"></a><tt class="py-lineno">221</tt> <tt class="py-line"><tt class="py-docstring"> Changes a file age using the C{os.utime} function.</tt> </tt>
384
<a name="L222"></a><tt class="py-lineno">222</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
385
<a name="L223"></a><tt class="py-lineno">223</tt> <tt class="py-line"><tt class="py-docstring"> @note: Some platforms don't seem to be able to set an age precisely. As a</tt> </tt>
386
<a name="L224"></a><tt class="py-lineno">224</tt> <tt class="py-line"><tt class="py-docstring"> result, whereas we might have intended to set an age of 86400 seconds, we</tt> </tt>
387
<a name="L225"></a><tt class="py-lineno">225</tt> <tt class="py-line"><tt class="py-docstring"> actually get an age of 86399.375 seconds. When util.calculateFileAge()</tt> </tt>
388
<a name="L226"></a><tt class="py-lineno">226</tt> <tt class="py-line"><tt class="py-docstring"> looks at that the file, it calculates an age of 0.999992766204 days, which</tt> </tt>
389
<a name="L227"></a><tt class="py-lineno">227</tt> <tt class="py-line"><tt class="py-docstring"> then gets truncated down to zero whole days. The tests get very confused.</tt> </tt>
390
<a name="L228"></a><tt class="py-lineno">228</tt> <tt class="py-line"><tt class="py-docstring"> To work around this, I always subtract off one additional second as a fudge</tt> </tt>
391
<a name="L229"></a><tt class="py-lineno">229</tt> <tt class="py-line"><tt class="py-docstring"> factor. That way, the file age will be I{at least} as old as requested</tt> </tt>
392
<a name="L230"></a><tt class="py-lineno">230</tt> <tt class="py-line"><tt class="py-docstring"> later on.</tt> </tt>
393
<a name="L231"></a><tt class="py-lineno">231</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
394
<a name="L232"></a><tt class="py-lineno">232</tt> <tt class="py-line"><tt class="py-docstring"> @param filename: File to operate on.</tt> </tt>
395
<a name="L233"></a><tt class="py-lineno">233</tt> <tt class="py-line"><tt class="py-docstring"> @param subtract: Number of seconds to subtract from the current time.</tt> </tt>
396
<a name="L234"></a><tt class="py-lineno">234</tt> <tt class="py-line"><tt class="py-docstring"> @raise ValueError: If a path cannot be encoded properly.</tt> </tt>
397
<a name="L235"></a><tt class="py-lineno">235</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
398
<a name="L236"></a><tt class="py-lineno">236</tt> <tt class="py-line"> <tt class="py-name">filename</tt> <tt class="py-op">=</tt> <tt id="link-18" class="py-name"><a title="CedarBackup2.util.encodePath" class="py-name" href="#" onclick="return doclink('link-18', 'encodePath', 'link-3');">encodePath</a></tt><tt class="py-op">(</tt><tt class="py-name">filename</tt><tt class="py-op">)</tt> </tt>
399
<a name="L237"></a><tt class="py-lineno">237</tt> <tt class="py-line"> <tt class="py-name">newTime</tt> <tt class="py-op">=</tt> <tt class="py-name">time</tt><tt class="py-op">.</tt><tt class="py-name">time</tt><tt class="py-op">(</tt><tt class="py-op">)</tt> <tt class="py-op">-</tt> <tt class="py-number">1</tt><tt class="py-op">;</tt> </tt>
400
<a name="L238"></a><tt class="py-lineno">238</tt> <tt class="py-line"> <tt class="py-keyword">if</tt> <tt class="py-name">subtract</tt> <tt class="py-keyword">is</tt> <tt class="py-keyword">not</tt> <tt class="py-name">None</tt><tt class="py-op">:</tt> </tt>
401
<a name="L239"></a><tt class="py-lineno">239</tt> <tt class="py-line"> <tt class="py-name">newTime</tt> <tt class="py-op">-=</tt> <tt class="py-name">subtract</tt> </tt>
402
<a name="L240"></a><tt class="py-lineno">240</tt> <tt class="py-line"> <tt class="py-name">os</tt><tt class="py-op">.</tt><tt class="py-name">utime</tt><tt class="py-op">(</tt><tt class="py-name">filename</tt><tt class="py-op">,</tt> <tt class="py-op">(</tt><tt class="py-name">newTime</tt><tt class="py-op">,</tt> <tt class="py-name">newTime</tt><tt class="py-op">)</tt><tt class="py-op">)</tt> </tt>
403
</div><a name="L241"></a><tt class="py-lineno">241</tt> <tt class="py-line"> </tt>
404
<a name="L242"></a><tt class="py-lineno">242</tt> <tt class="py-line"> </tt>
405
<a name="L243"></a><tt class="py-lineno">243</tt> <tt class="py-line"><tt class="py-comment">###########################</tt> </tt>
406
<a name="L244"></a><tt class="py-lineno">244</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># getMaskAsMode() function</tt> </tt>
407
<a name="L245"></a><tt class="py-lineno">245</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">###########################</tt> </tt>
408
<a name="L246"></a><tt class="py-lineno">246</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
409
<a name="getMaskAsMode"></a><div id="getMaskAsMode-def"><a name="L247"></a><tt class="py-lineno">247</tt> <a class="py-toggle" href="#" id="getMaskAsMode-toggle" onclick="return toggle('getMaskAsMode');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#getMaskAsMode">getMaskAsMode</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
410
</div><div id="getMaskAsMode-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="getMaskAsMode-expanded"><a name="L248"></a><tt class="py-lineno">248</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
411
<a name="L249"></a><tt class="py-lineno">249</tt> <tt class="py-line"><tt class="py-docstring"> Returns the user's current umask inverted to a mode.</tt> </tt>
412
<a name="L250"></a><tt class="py-lineno">250</tt> <tt class="py-line"><tt class="py-docstring"> A mode is mostly a bitwise inversion of a mask, i.e. mask 002 is mode 775.</tt> </tt>
413
<a name="L251"></a><tt class="py-lineno">251</tt> <tt class="py-line"><tt class="py-docstring"> @return: Umask converted to a mode, as an integer.</tt> </tt>
414
<a name="L252"></a><tt class="py-lineno">252</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
415
<a name="L253"></a><tt class="py-lineno">253</tt> <tt class="py-line"> <tt class="py-name">umask</tt> <tt class="py-op">=</tt> <tt class="py-name">os</tt><tt class="py-op">.</tt><tt class="py-name">umask</tt><tt class="py-op">(</tt><tt class="py-number">0777</tt><tt class="py-op">)</tt> </tt>
416
<a name="L254"></a><tt class="py-lineno">254</tt> <tt class="py-line"> <tt class="py-name">os</tt><tt class="py-op">.</tt><tt class="py-name">umask</tt><tt class="py-op">(</tt><tt class="py-name">umask</tt><tt class="py-op">)</tt> </tt>
417
<a name="L255"></a><tt class="py-lineno">255</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-name">int</tt><tt class="py-op">(</tt><tt class="py-op">~</tt><tt class="py-name">umask</tt> <tt class="py-op">&</tt> <tt class="py-number">0777</tt><tt class="py-op">)</tt> <tt class="py-comment"># invert, then use only lower bytes</tt> </tt>
418
</div><a name="L256"></a><tt class="py-lineno">256</tt> <tt class="py-line"> </tt>
419
<a name="L257"></a><tt class="py-lineno">257</tt> <tt class="py-line"> </tt>
420
<a name="L258"></a><tt class="py-lineno">258</tt> <tt class="py-line"><tt class="py-comment">######################</tt> </tt>
421
<a name="L259"></a><tt class="py-lineno">259</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># getLogin() function</tt> </tt>
422
<a name="L260"></a><tt class="py-lineno">260</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">######################</tt> </tt>
423
<a name="L261"></a><tt class="py-lineno">261</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
424
<a name="getLogin"></a><div id="getLogin-def"><a name="L262"></a><tt class="py-lineno">262</tt> <a class="py-toggle" href="#" id="getLogin-toggle" onclick="return toggle('getLogin');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#getLogin">getLogin</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
425
</div><div id="getLogin-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="getLogin-expanded"><a name="L263"></a><tt class="py-lineno">263</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
426
<a name="L264"></a><tt class="py-lineno">264</tt> <tt class="py-line"><tt class="py-docstring"> Returns the name of the currently-logged in user. This might fail under</tt> </tt>
427
<a name="L265"></a><tt class="py-lineno">265</tt> <tt class="py-line"><tt class="py-docstring"> some circumstances - but if it does, our tests would fail anyway.</tt> </tt>
428
<a name="L266"></a><tt class="py-lineno">266</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
429
<a name="L267"></a><tt class="py-lineno">267</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-name">getpass</tt><tt class="py-op">.</tt><tt class="py-name">getuser</tt><tt class="py-op">(</tt><tt class="py-op">)</tt> </tt>
430
</div><a name="L268"></a><tt class="py-lineno">268</tt> <tt class="py-line"> </tt>
431
<a name="L269"></a><tt class="py-lineno">269</tt> <tt class="py-line"> </tt>
432
<a name="L270"></a><tt class="py-lineno">270</tt> <tt class="py-line"><tt class="py-comment">############################</tt> </tt>
433
<a name="L271"></a><tt class="py-lineno">271</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># randomFilename() function</tt> </tt>
434
<a name="L272"></a><tt class="py-lineno">272</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">############################</tt> </tt>
435
<a name="L273"></a><tt class="py-lineno">273</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
436
<a name="randomFilename"></a><div id="randomFilename-def"><a name="L274"></a><tt class="py-lineno">274</tt> <a class="py-toggle" href="#" id="randomFilename-toggle" onclick="return toggle('randomFilename');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#randomFilename">randomFilename</a><tt class="py-op">(</tt><tt class="py-param">length</tt><tt class="py-op">,</tt> <tt class="py-param">prefix</tt><tt class="py-op">=</tt><tt class="py-name">None</tt><tt class="py-op">,</tt> <tt class="py-param">suffix</tt><tt class="py-op">=</tt><tt class="py-name">None</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
437
</div><div id="randomFilename-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="randomFilename-expanded"><a name="L275"></a><tt class="py-lineno">275</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
438
<a name="L276"></a><tt class="py-lineno">276</tt> <tt class="py-line"><tt class="py-docstring"> Generates a random filename with the given length.</tt> </tt>
439
<a name="L277"></a><tt class="py-lineno">277</tt> <tt class="py-line"><tt class="py-docstring"> @param length: Length of filename.</tt> </tt>
440
<a name="L278"></a><tt class="py-lineno">278</tt> <tt class="py-line"><tt class="py-docstring"> @return Random filename.</tt> </tt>
441
<a name="L279"></a><tt class="py-lineno">279</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
442
<a name="L280"></a><tt class="py-lineno">280</tt> <tt class="py-line"> <tt class="py-name">characters</tt> <tt class="py-op">=</tt> <tt class="py-op">[</tt><tt class="py-name">None</tt><tt class="py-op">]</tt> <tt class="py-op">*</tt> <tt class="py-name">length</tt> </tt>
443
<a name="L281"></a><tt class="py-lineno">281</tt> <tt class="py-line"> <tt class="py-keyword">for</tt> <tt class="py-name">i</tt> <tt class="py-keyword">in</tt> <tt class="py-name">xrange</tt><tt class="py-op">(</tt><tt class="py-name">length</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
444
<a name="L282"></a><tt class="py-lineno">282</tt> <tt class="py-line"> <tt class="py-name">characters</tt><tt class="py-op">[</tt><tt class="py-name">i</tt><tt class="py-op">]</tt> <tt class="py-op">=</tt> <tt class="py-name">random</tt><tt class="py-op">.</tt><tt class="py-name">choice</tt><tt class="py-op">(</tt><tt class="py-name">string</tt><tt class="py-op">.</tt><tt class="py-name">uppercase</tt><tt class="py-op">)</tt> </tt>
445
<a name="L283"></a><tt class="py-lineno">283</tt> <tt class="py-line"> <tt class="py-keyword">if</tt> <tt class="py-name">prefix</tt> <tt class="py-keyword">is</tt> <tt class="py-name">None</tt><tt class="py-op">:</tt> </tt>
446
<a name="L284"></a><tt class="py-lineno">284</tt> <tt class="py-line"> <tt class="py-name">prefix</tt> <tt class="py-op">=</tt> <tt class="py-string">""</tt> </tt>
447
<a name="L285"></a><tt class="py-lineno">285</tt> <tt class="py-line"> <tt class="py-keyword">if</tt> <tt class="py-name">suffix</tt> <tt class="py-keyword">is</tt> <tt class="py-name">None</tt><tt class="py-op">:</tt> </tt>
448
<a name="L286"></a><tt class="py-lineno">286</tt> <tt class="py-line"> <tt class="py-name">suffix</tt> <tt class="py-op">=</tt> <tt class="py-string">""</tt> </tt>
449
<a name="L287"></a><tt class="py-lineno">287</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-string">"%s%s%s"</tt> <tt class="py-op">%</tt> <tt class="py-op">(</tt><tt class="py-name">prefix</tt><tt class="py-op">,</tt> <tt class="py-string">""</tt><tt class="py-op">.</tt><tt class="py-name">join</tt><tt class="py-op">(</tt><tt class="py-name">characters</tt><tt class="py-op">)</tt><tt class="py-op">,</tt> <tt class="py-name">suffix</tt><tt class="py-op">)</tt> </tt>
450
</div><a name="L288"></a><tt class="py-lineno">288</tt> <tt class="py-line"> </tt>
451
<a name="L289"></a><tt class="py-lineno">289</tt> <tt class="py-line"> </tt>
452
<a name="L290"></a><tt class="py-lineno">290</tt> <tt class="py-line"><tt class="py-comment">####################################</tt> </tt>
453
<a name="L291"></a><tt class="py-lineno">291</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># failUnlessAssignRaises() function</tt> </tt>
454
<a name="L292"></a><tt class="py-lineno">292</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">####################################</tt> </tt>
455
<a name="L293"></a><tt class="py-lineno">293</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
456
<a name="failUnlessAssignRaises"></a><div id="failUnlessAssignRaises-def"><a name="L294"></a><tt class="py-lineno">294</tt> <a class="py-toggle" href="#" id="failUnlessAssignRaises-toggle" onclick="return toggle('failUnlessAssignRaises');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#failUnlessAssignRaises">failUnlessAssignRaises</a><tt class="py-op">(</tt><tt class="py-param">testCase</tt><tt class="py-op">,</tt> <tt class="py-param">exception</tt><tt class="py-op">,</tt> <tt class="py-param">object</tt><tt class="py-op">,</tt> <tt class="py-param">property</tt><tt class="py-op">,</tt> <tt class="py-param">value</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
457
</div><div id="failUnlessAssignRaises-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="failUnlessAssignRaises-expanded"><a name="L295"></a><tt class="py-lineno">295</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
458
<a name="L296"></a><tt class="py-lineno">296</tt> <tt class="py-line"><tt class="py-docstring"> Equivalent of C{failUnlessRaises}, but used for property assignments instead.</tt> </tt>
459
<a name="L297"></a><tt class="py-lineno">297</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
460
<a name="L298"></a><tt class="py-lineno">298</tt> <tt class="py-line"><tt class="py-docstring"> It's nice to be able to use C{failUnlessRaises} to check that a method call</tt> </tt>
461
<a name="L299"></a><tt class="py-lineno">299</tt> <tt class="py-line"><tt class="py-docstring"> raises the exception that you expect. Unfortunately, this method can't be</tt> </tt>
462
<a name="L300"></a><tt class="py-lineno">300</tt> <tt class="py-line"><tt class="py-docstring"> used to check Python propery assignments, even though these property</tt> </tt>
463
<a name="L301"></a><tt class="py-lineno">301</tt> <tt class="py-line"><tt class="py-docstring"> assignments are actually implemented underneath as methods.</tt> </tt>
464
<a name="L302"></a><tt class="py-lineno">302</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
465
<a name="L303"></a><tt class="py-lineno">303</tt> <tt class="py-line"><tt class="py-docstring"> This function (which can be easily called by unit test classes) provides an</tt> </tt>
466
<a name="L304"></a><tt class="py-lineno">304</tt> <tt class="py-line"><tt class="py-docstring"> easy way to wrap the assignment checks. It's not pretty, or as intuitive as</tt> </tt>
467
<a name="L305"></a><tt class="py-lineno">305</tt> <tt class="py-line"><tt class="py-docstring"> the original check it's modeled on, but it does work.</tt> </tt>
468
<a name="L306"></a><tt class="py-lineno">306</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
469
<a name="L307"></a><tt class="py-lineno">307</tt> <tt class="py-line"><tt class="py-docstring"> Let's assume you make this method call::</tt> </tt>
470
<a name="L308"></a><tt class="py-lineno">308</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
471
<a name="L309"></a><tt class="py-lineno">309</tt> <tt class="py-line"><tt class="py-docstring"> testCase.failUnlessAssignRaises(ValueError, collectDir, "absolutePath", absolutePath)</tt> </tt>
472
<a name="L310"></a><tt class="py-lineno">310</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
473
<a name="L311"></a><tt class="py-lineno">311</tt> <tt class="py-line"><tt class="py-docstring"> If you do this, a test case failure will be raised unless the assignment::</tt> </tt>
474
<a name="L312"></a><tt class="py-lineno">312</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
475
<a name="L313"></a><tt class="py-lineno">313</tt> <tt class="py-line"><tt class="py-docstring"> collectDir.absolutePath = absolutePath</tt> </tt>
476
<a name="L314"></a><tt class="py-lineno">314</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
477
<a name="L315"></a><tt class="py-lineno">315</tt> <tt class="py-line"><tt class="py-docstring"> fails with a C{ValueError} exception. The failure message differentiates</tt> </tt>
478
<a name="L316"></a><tt class="py-lineno">316</tt> <tt class="py-line"><tt class="py-docstring"> between the case where no exception was raised and the case where the wrong</tt> </tt>
479
<a name="L317"></a><tt class="py-lineno">317</tt> <tt class="py-line"><tt class="py-docstring"> exception was raised.</tt> </tt>
480
<a name="L318"></a><tt class="py-lineno">318</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
481
<a name="L319"></a><tt class="py-lineno">319</tt> <tt class="py-line"><tt class="py-docstring"> @note: Internally, the C{missed} and C{instead} variables are used rather</tt> </tt>
482
<a name="L320"></a><tt class="py-lineno">320</tt> <tt class="py-line"><tt class="py-docstring"> than directly calling C{testCase.fail} upon noticing a problem because the</tt> </tt>
483
<a name="L321"></a><tt class="py-lineno">321</tt> <tt class="py-line"><tt class="py-docstring"> act of "failure" itself generates an exception that would be caught by the</tt> </tt>
484
<a name="L322"></a><tt class="py-lineno">322</tt> <tt class="py-line"><tt class="py-docstring"> general C{except} clause.</tt> </tt>
485
<a name="L323"></a><tt class="py-lineno">323</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
486
<a name="L324"></a><tt class="py-lineno">324</tt> <tt class="py-line"><tt class="py-docstring"> @param testCase: PyUnit test case object (i.e. self).</tt> </tt>
487
<a name="L325"></a><tt class="py-lineno">325</tt> <tt class="py-line"><tt class="py-docstring"> @param exception: Exception that is expected to be raised.</tt> </tt>
488
<a name="L326"></a><tt class="py-lineno">326</tt> <tt class="py-line"><tt class="py-docstring"> @param object: Object whose property is to be assigned to.</tt> </tt>
489
<a name="L327"></a><tt class="py-lineno">327</tt> <tt class="py-line"><tt class="py-docstring"> @param property: Name of the property, as a string.</tt> </tt>
490
<a name="L328"></a><tt class="py-lineno">328</tt> <tt class="py-line"><tt class="py-docstring"> @param value: Value that is to be assigned to the property.</tt> </tt>
491
<a name="L329"></a><tt class="py-lineno">329</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
492
<a name="L330"></a><tt class="py-lineno">330</tt> <tt class="py-line"><tt class="py-docstring"> @see: C{unittest.TestCase.failUnlessRaises}</tt> </tt>
493
<a name="L331"></a><tt class="py-lineno">331</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
494
<a name="L332"></a><tt class="py-lineno">332</tt> <tt class="py-line"> <tt class="py-name">missed</tt> <tt class="py-op">=</tt> <tt class="py-name">False</tt> </tt>
495
<a name="L333"></a><tt class="py-lineno">333</tt> <tt class="py-line"> <tt class="py-name">instead</tt> <tt class="py-op">=</tt> <tt class="py-name">None</tt> </tt>
496
<a name="L334"></a><tt class="py-lineno">334</tt> <tt class="py-line"> <tt class="py-keyword">try</tt><tt class="py-op">:</tt> </tt>
497
<a name="L335"></a><tt class="py-lineno">335</tt> <tt class="py-line"> <tt class="py-keyword">exec</tt> <tt class="py-string">"object.%s = value"</tt> <tt class="py-op">%</tt> <tt class="py-name">property</tt> </tt>
498
<a name="L336"></a><tt class="py-lineno">336</tt> <tt class="py-line"> <tt class="py-name">missed</tt> <tt class="py-op">=</tt> <tt class="py-name">True</tt> </tt>
499
<a name="L337"></a><tt class="py-lineno">337</tt> <tt class="py-line"> <tt class="py-keyword">except</tt> <tt class="py-name">exception</tt><tt class="py-op">:</tt> <tt class="py-keyword">pass</tt> </tt>
500
<a name="L338"></a><tt class="py-lineno">338</tt> <tt class="py-line"> <tt class="py-keyword">except</tt> <tt class="py-name">Exception</tt><tt class="py-op">,</tt> <tt class="py-name">e</tt><tt class="py-op">:</tt> <tt class="py-name">instead</tt> <tt class="py-op">=</tt> <tt class="py-name">e</tt> </tt>
501
<a name="L339"></a><tt class="py-lineno">339</tt> <tt class="py-line"> <tt class="py-keyword">if</tt> <tt class="py-name">missed</tt><tt class="py-op">:</tt> </tt>
502
<a name="L340"></a><tt class="py-lineno">340</tt> <tt class="py-line"> <tt class="py-name">testCase</tt><tt class="py-op">.</tt><tt class="py-name">fail</tt><tt class="py-op">(</tt><tt class="py-string">"Expected assignment to raise %s, but got no exception."</tt> <tt class="py-op">%</tt> <tt class="py-op">(</tt><tt class="py-name">exception</tt><tt class="py-op">.</tt><tt class="py-name">__name__</tt><tt class="py-op">)</tt><tt class="py-op">)</tt> </tt>
503
<a name="L341"></a><tt class="py-lineno">341</tt> <tt class="py-line"> <tt class="py-keyword">if</tt> <tt class="py-name">instead</tt> <tt class="py-keyword">is</tt> <tt class="py-keyword">not</tt> <tt class="py-name">None</tt><tt class="py-op">:</tt> </tt>
504
<a name="L342"></a><tt class="py-lineno">342</tt> <tt class="py-line"> <tt class="py-name">testCase</tt><tt class="py-op">.</tt><tt class="py-name">fail</tt><tt class="py-op">(</tt><tt class="py-string">"Expected assignment to raise %s, but got %s instead."</tt> <tt class="py-op">%</tt> <tt class="py-op">(</tt><tt class="py-name">ValueError</tt><tt class="py-op">,</tt> <tt class="py-name">instead</tt><tt class="py-op">.</tt><tt class="py-name">__class__</tt><tt class="py-op">.</tt><tt class="py-name">__name__</tt><tt class="py-op">)</tt><tt class="py-op">)</tt> </tt>
505
</div><a name="L343"></a><tt class="py-lineno">343</tt> <tt class="py-line"> </tt>
506
<a name="L344"></a><tt class="py-lineno">344</tt> <tt class="py-line"> </tt>
507
<a name="L345"></a><tt class="py-lineno">345</tt> <tt class="py-line"><tt class="py-comment">###########################</tt> </tt>
508
<a name="L346"></a><tt class="py-lineno">346</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># captureOutput() function</tt> </tt>
509
<a name="L347"></a><tt class="py-lineno">347</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">###########################</tt> </tt>
510
<a name="L348"></a><tt class="py-lineno">348</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
511
<a name="captureOutput"></a><div id="captureOutput-def"><a name="L349"></a><tt class="py-lineno">349</tt> <a class="py-toggle" href="#" id="captureOutput-toggle" onclick="return toggle('captureOutput');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#captureOutput">captureOutput</a><tt class="py-op">(</tt><tt class="py-param">callable</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
512
</div><div id="captureOutput-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="captureOutput-expanded"><a name="L350"></a><tt class="py-lineno">350</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
513
<a name="L351"></a><tt class="py-lineno">351</tt> <tt class="py-line"><tt class="py-docstring"> Captures the output (stdout, stderr) of a function or a method.</tt> </tt>
514
<a name="L352"></a><tt class="py-lineno">352</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
515
<a name="L353"></a><tt class="py-lineno">353</tt> <tt class="py-line"><tt class="py-docstring"> Some of our functions don't do anything other than just print output. We</tt> </tt>
516
<a name="L354"></a><tt class="py-lineno">354</tt> <tt class="py-line"><tt class="py-docstring"> need a way to test these functions (at least nominally) but we don't want</tt> </tt>
517
<a name="L355"></a><tt class="py-lineno">355</tt> <tt class="py-line"><tt class="py-docstring"> any of the output spoiling the test suite output.</tt> </tt>
518
<a name="L356"></a><tt class="py-lineno">356</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
519
<a name="L357"></a><tt class="py-lineno">357</tt> <tt class="py-line"><tt class="py-docstring"> This function just creates a dummy file descriptor that can be used as a</tt> </tt>
520
<a name="L358"></a><tt class="py-lineno">358</tt> <tt class="py-line"><tt class="py-docstring"> target by the callable function, rather than C{stdout} or C{stderr}.</tt> </tt>
372
<a name="L210"></a><tt class="py-lineno">210</tt> <tt class="py-line"> <tt class="py-keyword">try</tt><tt class="py-op">:</tt> </tt>
373
<a name="L211"></a><tt class="py-lineno">211</tt> <tt class="py-line"> <tt class="py-name">tar</tt><tt class="py-op">.</tt><tt class="py-name">format</tt> <tt class="py-op">=</tt> <tt class="py-name">tarfile</tt><tt class="py-op">.</tt><tt class="py-name">GNU_FORMAT</tt> </tt>
374
<a name="L212"></a><tt class="py-lineno">212</tt> <tt class="py-line"> <tt class="py-keyword">except</tt><tt class="py-op">:</tt> </tt>
375
<a name="L213"></a><tt class="py-lineno">213</tt> <tt class="py-line"> <tt class="py-name">tar</tt><tt class="py-op">.</tt><tt class="py-name">posix</tt> <tt class="py-op">=</tt> <tt class="py-name">False</tt> </tt>
376
<a name="L214"></a><tt class="py-lineno">214</tt> <tt class="py-line"> <tt class="py-keyword">for</tt> <tt class="py-name">tarinfo</tt> <tt class="py-keyword">in</tt> <tt class="py-name">tar</tt><tt class="py-op">:</tt> </tt>
377
<a name="L215"></a><tt class="py-lineno">215</tt> <tt class="py-line"> <tt class="py-name">tar</tt><tt class="py-op">.</tt><tt class="py-name">extract</tt><tt class="py-op">(</tt><tt class="py-name">tarinfo</tt><tt class="py-op">,</tt> <tt class="py-name">tmpdir</tt><tt class="py-op">)</tt> </tt>
378
</div><a name="L216"></a><tt class="py-lineno">216</tt> <tt class="py-line"> </tt>
379
<a name="L217"></a><tt class="py-lineno">217</tt> <tt class="py-line"> </tt>
380
<a name="L218"></a><tt class="py-lineno">218</tt> <tt class="py-line"><tt class="py-comment">###########################</tt> </tt>
381
<a name="L219"></a><tt class="py-lineno">219</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># changeFileAge() function</tt> </tt>
382
<a name="L220"></a><tt class="py-lineno">220</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">###########################</tt> </tt>
383
<a name="L221"></a><tt class="py-lineno">221</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
384
<a name="changeFileAge"></a><div id="changeFileAge-def"><a name="L222"></a><tt class="py-lineno">222</tt> <a class="py-toggle" href="#" id="changeFileAge-toggle" onclick="return toggle('changeFileAge');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#changeFileAge">changeFileAge</a><tt class="py-op">(</tt><tt class="py-param">filename</tt><tt class="py-op">,</tt> <tt class="py-param">subtract</tt><tt class="py-op">=</tt><tt class="py-name">None</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
385
</div><div id="changeFileAge-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="changeFileAge-expanded"><a name="L223"></a><tt class="py-lineno">223</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
386
<a name="L224"></a><tt class="py-lineno">224</tt> <tt class="py-line"><tt class="py-docstring"> Changes a file age using the C{os.utime} function.</tt> </tt>
387
<a name="L225"></a><tt class="py-lineno">225</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
388
<a name="L226"></a><tt class="py-lineno">226</tt> <tt class="py-line"><tt class="py-docstring"> @note: Some platforms don't seem to be able to set an age precisely. As a</tt> </tt>
389
<a name="L227"></a><tt class="py-lineno">227</tt> <tt class="py-line"><tt class="py-docstring"> result, whereas we might have intended to set an age of 86400 seconds, we</tt> </tt>
390
<a name="L228"></a><tt class="py-lineno">228</tt> <tt class="py-line"><tt class="py-docstring"> actually get an age of 86399.375 seconds. When util.calculateFileAge()</tt> </tt>
391
<a name="L229"></a><tt class="py-lineno">229</tt> <tt class="py-line"><tt class="py-docstring"> looks at that the file, it calculates an age of 0.999992766204 days, which</tt> </tt>
392
<a name="L230"></a><tt class="py-lineno">230</tt> <tt class="py-line"><tt class="py-docstring"> then gets truncated down to zero whole days. The tests get very confused.</tt> </tt>
393
<a name="L231"></a><tt class="py-lineno">231</tt> <tt class="py-line"><tt class="py-docstring"> To work around this, I always subtract off one additional second as a fudge</tt> </tt>
394
<a name="L232"></a><tt class="py-lineno">232</tt> <tt class="py-line"><tt class="py-docstring"> factor. That way, the file age will be I{at least} as old as requested</tt> </tt>
395
<a name="L233"></a><tt class="py-lineno">233</tt> <tt class="py-line"><tt class="py-docstring"> later on.</tt> </tt>
396
<a name="L234"></a><tt class="py-lineno">234</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
397
<a name="L235"></a><tt class="py-lineno">235</tt> <tt class="py-line"><tt class="py-docstring"> @param filename: File to operate on.</tt> </tt>
398
<a name="L236"></a><tt class="py-lineno">236</tt> <tt class="py-line"><tt class="py-docstring"> @param subtract: Number of seconds to subtract from the current time.</tt> </tt>
399
<a name="L237"></a><tt class="py-lineno">237</tt> <tt class="py-line"><tt class="py-docstring"> @raise ValueError: If a path cannot be encoded properly.</tt> </tt>
400
<a name="L238"></a><tt class="py-lineno">238</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
401
<a name="L239"></a><tt class="py-lineno">239</tt> <tt class="py-line"> <tt class="py-name">filename</tt> <tt class="py-op">=</tt> <tt id="link-18" class="py-name"><a title="CedarBackup2.util.encodePath" class="py-name" href="#" onclick="return doclink('link-18', 'encodePath', 'link-3');">encodePath</a></tt><tt class="py-op">(</tt><tt class="py-name">filename</tt><tt class="py-op">)</tt> </tt>
402
<a name="L240"></a><tt class="py-lineno">240</tt> <tt class="py-line"> <tt class="py-name">newTime</tt> <tt class="py-op">=</tt> <tt class="py-name">time</tt><tt class="py-op">.</tt><tt class="py-name">time</tt><tt class="py-op">(</tt><tt class="py-op">)</tt> <tt class="py-op">-</tt> <tt class="py-number">1</tt><tt class="py-op">;</tt> </tt>
403
<a name="L241"></a><tt class="py-lineno">241</tt> <tt class="py-line"> <tt class="py-keyword">if</tt> <tt class="py-name">subtract</tt> <tt class="py-keyword">is</tt> <tt class="py-keyword">not</tt> <tt class="py-name">None</tt><tt class="py-op">:</tt> </tt>
404
<a name="L242"></a><tt class="py-lineno">242</tt> <tt class="py-line"> <tt class="py-name">newTime</tt> <tt class="py-op">-=</tt> <tt class="py-name">subtract</tt> </tt>
405
<a name="L243"></a><tt class="py-lineno">243</tt> <tt class="py-line"> <tt class="py-name">os</tt><tt class="py-op">.</tt><tt class="py-name">utime</tt><tt class="py-op">(</tt><tt class="py-name">filename</tt><tt class="py-op">,</tt> <tt class="py-op">(</tt><tt class="py-name">newTime</tt><tt class="py-op">,</tt> <tt class="py-name">newTime</tt><tt class="py-op">)</tt><tt class="py-op">)</tt> </tt>
406
</div><a name="L244"></a><tt class="py-lineno">244</tt> <tt class="py-line"> </tt>
407
<a name="L245"></a><tt class="py-lineno">245</tt> <tt class="py-line"> </tt>
408
<a name="L246"></a><tt class="py-lineno">246</tt> <tt class="py-line"><tt class="py-comment">###########################</tt> </tt>
409
<a name="L247"></a><tt class="py-lineno">247</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># getMaskAsMode() function</tt> </tt>
410
<a name="L248"></a><tt class="py-lineno">248</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">###########################</tt> </tt>
411
<a name="L249"></a><tt class="py-lineno">249</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
412
<a name="getMaskAsMode"></a><div id="getMaskAsMode-def"><a name="L250"></a><tt class="py-lineno">250</tt> <a class="py-toggle" href="#" id="getMaskAsMode-toggle" onclick="return toggle('getMaskAsMode');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#getMaskAsMode">getMaskAsMode</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
413
</div><div id="getMaskAsMode-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="getMaskAsMode-expanded"><a name="L251"></a><tt class="py-lineno">251</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
414
<a name="L252"></a><tt class="py-lineno">252</tt> <tt class="py-line"><tt class="py-docstring"> Returns the user's current umask inverted to a mode.</tt> </tt>
415
<a name="L253"></a><tt class="py-lineno">253</tt> <tt class="py-line"><tt class="py-docstring"> A mode is mostly a bitwise inversion of a mask, i.e. mask 002 is mode 775.</tt> </tt>
416
<a name="L254"></a><tt class="py-lineno">254</tt> <tt class="py-line"><tt class="py-docstring"> @return: Umask converted to a mode, as an integer.</tt> </tt>
417
<a name="L255"></a><tt class="py-lineno">255</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
418
<a name="L256"></a><tt class="py-lineno">256</tt> <tt class="py-line"> <tt class="py-name">umask</tt> <tt class="py-op">=</tt> <tt class="py-name">os</tt><tt class="py-op">.</tt><tt class="py-name">umask</tt><tt class="py-op">(</tt><tt class="py-number">0777</tt><tt class="py-op">)</tt> </tt>
419
<a name="L257"></a><tt class="py-lineno">257</tt> <tt class="py-line"> <tt class="py-name">os</tt><tt class="py-op">.</tt><tt class="py-name">umask</tt><tt class="py-op">(</tt><tt class="py-name">umask</tt><tt class="py-op">)</tt> </tt>
420
<a name="L258"></a><tt class="py-lineno">258</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-name">int</tt><tt class="py-op">(</tt><tt class="py-op">~</tt><tt class="py-name">umask</tt> <tt class="py-op">&</tt> <tt class="py-number">0777</tt><tt class="py-op">)</tt> <tt class="py-comment"># invert, then use only lower bytes</tt> </tt>
421
</div><a name="L259"></a><tt class="py-lineno">259</tt> <tt class="py-line"> </tt>
422
<a name="L260"></a><tt class="py-lineno">260</tt> <tt class="py-line"> </tt>
423
<a name="L261"></a><tt class="py-lineno">261</tt> <tt class="py-line"><tt class="py-comment">######################</tt> </tt>
424
<a name="L262"></a><tt class="py-lineno">262</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># getLogin() function</tt> </tt>
425
<a name="L263"></a><tt class="py-lineno">263</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">######################</tt> </tt>
426
<a name="L264"></a><tt class="py-lineno">264</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
427
<a name="getLogin"></a><div id="getLogin-def"><a name="L265"></a><tt class="py-lineno">265</tt> <a class="py-toggle" href="#" id="getLogin-toggle" onclick="return toggle('getLogin');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#getLogin">getLogin</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
428
</div><div id="getLogin-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="getLogin-expanded"><a name="L266"></a><tt class="py-lineno">266</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
429
<a name="L267"></a><tt class="py-lineno">267</tt> <tt class="py-line"><tt class="py-docstring"> Returns the name of the currently-logged in user. This might fail under</tt> </tt>
430
<a name="L268"></a><tt class="py-lineno">268</tt> <tt class="py-line"><tt class="py-docstring"> some circumstances - but if it does, our tests would fail anyway.</tt> </tt>
431
<a name="L269"></a><tt class="py-lineno">269</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
432
<a name="L270"></a><tt class="py-lineno">270</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-name">getpass</tt><tt class="py-op">.</tt><tt class="py-name">getuser</tt><tt class="py-op">(</tt><tt class="py-op">)</tt> </tt>
433
</div><a name="L271"></a><tt class="py-lineno">271</tt> <tt class="py-line"> </tt>
434
<a name="L272"></a><tt class="py-lineno">272</tt> <tt class="py-line"> </tt>
435
<a name="L273"></a><tt class="py-lineno">273</tt> <tt class="py-line"><tt class="py-comment">############################</tt> </tt>
436
<a name="L274"></a><tt class="py-lineno">274</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># randomFilename() function</tt> </tt>
437
<a name="L275"></a><tt class="py-lineno">275</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">############################</tt> </tt>
438
<a name="L276"></a><tt class="py-lineno">276</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
439
<a name="randomFilename"></a><div id="randomFilename-def"><a name="L277"></a><tt class="py-lineno">277</tt> <a class="py-toggle" href="#" id="randomFilename-toggle" onclick="return toggle('randomFilename');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#randomFilename">randomFilename</a><tt class="py-op">(</tt><tt class="py-param">length</tt><tt class="py-op">,</tt> <tt class="py-param">prefix</tt><tt class="py-op">=</tt><tt class="py-name">None</tt><tt class="py-op">,</tt> <tt class="py-param">suffix</tt><tt class="py-op">=</tt><tt class="py-name">None</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
440
</div><div id="randomFilename-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="randomFilename-expanded"><a name="L278"></a><tt class="py-lineno">278</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
441
<a name="L279"></a><tt class="py-lineno">279</tt> <tt class="py-line"><tt class="py-docstring"> Generates a random filename with the given length.</tt> </tt>
442
<a name="L280"></a><tt class="py-lineno">280</tt> <tt class="py-line"><tt class="py-docstring"> @param length: Length of filename.</tt> </tt>
443
<a name="L281"></a><tt class="py-lineno">281</tt> <tt class="py-line"><tt class="py-docstring"> @return Random filename.</tt> </tt>
444
<a name="L282"></a><tt class="py-lineno">282</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
445
<a name="L283"></a><tt class="py-lineno">283</tt> <tt class="py-line"> <tt class="py-name">characters</tt> <tt class="py-op">=</tt> <tt class="py-op">[</tt><tt class="py-name">None</tt><tt class="py-op">]</tt> <tt class="py-op">*</tt> <tt class="py-name">length</tt> </tt>
446
<a name="L284"></a><tt class="py-lineno">284</tt> <tt class="py-line"> <tt class="py-keyword">for</tt> <tt class="py-name">i</tt> <tt class="py-keyword">in</tt> <tt class="py-name">xrange</tt><tt class="py-op">(</tt><tt class="py-name">length</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
447
<a name="L285"></a><tt class="py-lineno">285</tt> <tt class="py-line"> <tt class="py-name">characters</tt><tt class="py-op">[</tt><tt class="py-name">i</tt><tt class="py-op">]</tt> <tt class="py-op">=</tt> <tt class="py-name">random</tt><tt class="py-op">.</tt><tt class="py-name">choice</tt><tt class="py-op">(</tt><tt class="py-name">string</tt><tt class="py-op">.</tt><tt class="py-name">uppercase</tt><tt class="py-op">)</tt> </tt>
448
<a name="L286"></a><tt class="py-lineno">286</tt> <tt class="py-line"> <tt class="py-keyword">if</tt> <tt class="py-name">prefix</tt> <tt class="py-keyword">is</tt> <tt class="py-name">None</tt><tt class="py-op">:</tt> </tt>
449
<a name="L287"></a><tt class="py-lineno">287</tt> <tt class="py-line"> <tt class="py-name">prefix</tt> <tt class="py-op">=</tt> <tt class="py-string">""</tt> </tt>
450
<a name="L288"></a><tt class="py-lineno">288</tt> <tt class="py-line"> <tt class="py-keyword">if</tt> <tt class="py-name">suffix</tt> <tt class="py-keyword">is</tt> <tt class="py-name">None</tt><tt class="py-op">:</tt> </tt>
451
<a name="L289"></a><tt class="py-lineno">289</tt> <tt class="py-line"> <tt class="py-name">suffix</tt> <tt class="py-op">=</tt> <tt class="py-string">""</tt> </tt>
452
<a name="L290"></a><tt class="py-lineno">290</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-string">"%s%s%s"</tt> <tt class="py-op">%</tt> <tt class="py-op">(</tt><tt class="py-name">prefix</tt><tt class="py-op">,</tt> <tt class="py-string">""</tt><tt class="py-op">.</tt><tt class="py-name">join</tt><tt class="py-op">(</tt><tt class="py-name">characters</tt><tt class="py-op">)</tt><tt class="py-op">,</tt> <tt class="py-name">suffix</tt><tt class="py-op">)</tt> </tt>
453
</div><a name="L291"></a><tt class="py-lineno">291</tt> <tt class="py-line"> </tt>
454
<a name="L292"></a><tt class="py-lineno">292</tt> <tt class="py-line"> </tt>
455
<a name="L293"></a><tt class="py-lineno">293</tt> <tt class="py-line"><tt class="py-comment">####################################</tt> </tt>
456
<a name="L294"></a><tt class="py-lineno">294</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># failUnlessAssignRaises() function</tt> </tt>
457
<a name="L295"></a><tt class="py-lineno">295</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">####################################</tt> </tt>
458
<a name="L296"></a><tt class="py-lineno">296</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
459
<a name="failUnlessAssignRaises"></a><div id="failUnlessAssignRaises-def"><a name="L297"></a><tt class="py-lineno">297</tt> <a class="py-toggle" href="#" id="failUnlessAssignRaises-toggle" onclick="return toggle('failUnlessAssignRaises');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#failUnlessAssignRaises">failUnlessAssignRaises</a><tt class="py-op">(</tt><tt class="py-param">testCase</tt><tt class="py-op">,</tt> <tt class="py-param">exception</tt><tt class="py-op">,</tt> <tt class="py-param">object</tt><tt class="py-op">,</tt> <tt class="py-param">property</tt><tt class="py-op">,</tt> <tt class="py-param">value</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
460
</div><div id="failUnlessAssignRaises-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="failUnlessAssignRaises-expanded"><a name="L298"></a><tt class="py-lineno">298</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
461
<a name="L299"></a><tt class="py-lineno">299</tt> <tt class="py-line"><tt class="py-docstring"> Equivalent of C{failUnlessRaises}, but used for property assignments instead.</tt> </tt>
462
<a name="L300"></a><tt class="py-lineno">300</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
463
<a name="L301"></a><tt class="py-lineno">301</tt> <tt class="py-line"><tt class="py-docstring"> It's nice to be able to use C{failUnlessRaises} to check that a method call</tt> </tt>
464
<a name="L302"></a><tt class="py-lineno">302</tt> <tt class="py-line"><tt class="py-docstring"> raises the exception that you expect. Unfortunately, this method can't be</tt> </tt>
465
<a name="L303"></a><tt class="py-lineno">303</tt> <tt class="py-line"><tt class="py-docstring"> used to check Python propery assignments, even though these property</tt> </tt>
466
<a name="L304"></a><tt class="py-lineno">304</tt> <tt class="py-line"><tt class="py-docstring"> assignments are actually implemented underneath as methods.</tt> </tt>
467
<a name="L305"></a><tt class="py-lineno">305</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
468
<a name="L306"></a><tt class="py-lineno">306</tt> <tt class="py-line"><tt class="py-docstring"> This function (which can be easily called by unit test classes) provides an</tt> </tt>
469
<a name="L307"></a><tt class="py-lineno">307</tt> <tt class="py-line"><tt class="py-docstring"> easy way to wrap the assignment checks. It's not pretty, or as intuitive as</tt> </tt>
470
<a name="L308"></a><tt class="py-lineno">308</tt> <tt class="py-line"><tt class="py-docstring"> the original check it's modeled on, but it does work.</tt> </tt>
471
<a name="L309"></a><tt class="py-lineno">309</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
472
<a name="L310"></a><tt class="py-lineno">310</tt> <tt class="py-line"><tt class="py-docstring"> Let's assume you make this method call::</tt> </tt>
473
<a name="L311"></a><tt class="py-lineno">311</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
474
<a name="L312"></a><tt class="py-lineno">312</tt> <tt class="py-line"><tt class="py-docstring"> testCase.failUnlessAssignRaises(ValueError, collectDir, "absolutePath", absolutePath)</tt> </tt>
475
<a name="L313"></a><tt class="py-lineno">313</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
476
<a name="L314"></a><tt class="py-lineno">314</tt> <tt class="py-line"><tt class="py-docstring"> If you do this, a test case failure will be raised unless the assignment::</tt> </tt>
477
<a name="L315"></a><tt class="py-lineno">315</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
478
<a name="L316"></a><tt class="py-lineno">316</tt> <tt class="py-line"><tt class="py-docstring"> collectDir.absolutePath = absolutePath</tt> </tt>
479
<a name="L317"></a><tt class="py-lineno">317</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
480
<a name="L318"></a><tt class="py-lineno">318</tt> <tt class="py-line"><tt class="py-docstring"> fails with a C{ValueError} exception. The failure message differentiates</tt> </tt>
481
<a name="L319"></a><tt class="py-lineno">319</tt> <tt class="py-line"><tt class="py-docstring"> between the case where no exception was raised and the case where the wrong</tt> </tt>
482
<a name="L320"></a><tt class="py-lineno">320</tt> <tt class="py-line"><tt class="py-docstring"> exception was raised.</tt> </tt>
483
<a name="L321"></a><tt class="py-lineno">321</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
484
<a name="L322"></a><tt class="py-lineno">322</tt> <tt class="py-line"><tt class="py-docstring"> @note: Internally, the C{missed} and C{instead} variables are used rather</tt> </tt>
485
<a name="L323"></a><tt class="py-lineno">323</tt> <tt class="py-line"><tt class="py-docstring"> than directly calling C{testCase.fail} upon noticing a problem because the</tt> </tt>
486
<a name="L324"></a><tt class="py-lineno">324</tt> <tt class="py-line"><tt class="py-docstring"> act of "failure" itself generates an exception that would be caught by the</tt> </tt>
487
<a name="L325"></a><tt class="py-lineno">325</tt> <tt class="py-line"><tt class="py-docstring"> general C{except} clause.</tt> </tt>
488
<a name="L326"></a><tt class="py-lineno">326</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
489
<a name="L327"></a><tt class="py-lineno">327</tt> <tt class="py-line"><tt class="py-docstring"> @param testCase: PyUnit test case object (i.e. self).</tt> </tt>
490
<a name="L328"></a><tt class="py-lineno">328</tt> <tt class="py-line"><tt class="py-docstring"> @param exception: Exception that is expected to be raised.</tt> </tt>
491
<a name="L329"></a><tt class="py-lineno">329</tt> <tt class="py-line"><tt class="py-docstring"> @param object: Object whose property is to be assigned to.</tt> </tt>
492
<a name="L330"></a><tt class="py-lineno">330</tt> <tt class="py-line"><tt class="py-docstring"> @param property: Name of the property, as a string.</tt> </tt>
493
<a name="L331"></a><tt class="py-lineno">331</tt> <tt class="py-line"><tt class="py-docstring"> @param value: Value that is to be assigned to the property.</tt> </tt>
494
<a name="L332"></a><tt class="py-lineno">332</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
495
<a name="L333"></a><tt class="py-lineno">333</tt> <tt class="py-line"><tt class="py-docstring"> @see: C{unittest.TestCase.failUnlessRaises}</tt> </tt>
496
<a name="L334"></a><tt class="py-lineno">334</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
497
<a name="L335"></a><tt class="py-lineno">335</tt> <tt class="py-line"> <tt class="py-name">missed</tt> <tt class="py-op">=</tt> <tt class="py-name">False</tt> </tt>
498
<a name="L336"></a><tt class="py-lineno">336</tt> <tt class="py-line"> <tt class="py-name">instead</tt> <tt class="py-op">=</tt> <tt class="py-name">None</tt> </tt>
499
<a name="L337"></a><tt class="py-lineno">337</tt> <tt class="py-line"> <tt class="py-keyword">try</tt><tt class="py-op">:</tt> </tt>
500
<a name="L338"></a><tt class="py-lineno">338</tt> <tt class="py-line"> <tt class="py-keyword">exec</tt> <tt class="py-string">"object.%s = value"</tt> <tt class="py-op">%</tt> <tt class="py-name">property</tt> </tt>
501
<a name="L339"></a><tt class="py-lineno">339</tt> <tt class="py-line"> <tt class="py-name">missed</tt> <tt class="py-op">=</tt> <tt class="py-name">True</tt> </tt>
502
<a name="L340"></a><tt class="py-lineno">340</tt> <tt class="py-line"> <tt class="py-keyword">except</tt> <tt class="py-name">exception</tt><tt class="py-op">:</tt> <tt class="py-keyword">pass</tt> </tt>
503
<a name="L341"></a><tt class="py-lineno">341</tt> <tt class="py-line"> <tt class="py-keyword">except</tt> <tt class="py-name">Exception</tt><tt class="py-op">,</tt> <tt class="py-name">e</tt><tt class="py-op">:</tt> <tt class="py-name">instead</tt> <tt class="py-op">=</tt> <tt class="py-name">e</tt> </tt>
504
<a name="L342"></a><tt class="py-lineno">342</tt> <tt class="py-line"> <tt class="py-keyword">if</tt> <tt class="py-name">missed</tt><tt class="py-op">:</tt> </tt>
505
<a name="L343"></a><tt class="py-lineno">343</tt> <tt class="py-line"> <tt class="py-name">testCase</tt><tt class="py-op">.</tt><tt class="py-name">fail</tt><tt class="py-op">(</tt><tt class="py-string">"Expected assignment to raise %s, but got no exception."</tt> <tt class="py-op">%</tt> <tt class="py-op">(</tt><tt class="py-name">exception</tt><tt class="py-op">.</tt><tt class="py-name">__name__</tt><tt class="py-op">)</tt><tt class="py-op">)</tt> </tt>
506
<a name="L344"></a><tt class="py-lineno">344</tt> <tt class="py-line"> <tt class="py-keyword">if</tt> <tt class="py-name">instead</tt> <tt class="py-keyword">is</tt> <tt class="py-keyword">not</tt> <tt class="py-name">None</tt><tt class="py-op">:</tt> </tt>
507
<a name="L345"></a><tt class="py-lineno">345</tt> <tt class="py-line"> <tt class="py-name">testCase</tt><tt class="py-op">.</tt><tt class="py-name">fail</tt><tt class="py-op">(</tt><tt class="py-string">"Expected assignment to raise %s, but got %s instead."</tt> <tt class="py-op">%</tt> <tt class="py-op">(</tt><tt class="py-name">ValueError</tt><tt class="py-op">,</tt> <tt class="py-name">instead</tt><tt class="py-op">.</tt><tt class="py-name">__class__</tt><tt class="py-op">.</tt><tt class="py-name">__name__</tt><tt class="py-op">)</tt><tt class="py-op">)</tt> </tt>
508
</div><a name="L346"></a><tt class="py-lineno">346</tt> <tt class="py-line"> </tt>
509
<a name="L347"></a><tt class="py-lineno">347</tt> <tt class="py-line"> </tt>
510
<a name="L348"></a><tt class="py-lineno">348</tt> <tt class="py-line"><tt class="py-comment">###########################</tt> </tt>
511
<a name="L349"></a><tt class="py-lineno">349</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># captureOutput() function</tt> </tt>
512
<a name="L350"></a><tt class="py-lineno">350</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">###########################</tt> </tt>
513
<a name="L351"></a><tt class="py-lineno">351</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
514
<a name="captureOutput"></a><div id="captureOutput-def"><a name="L352"></a><tt class="py-lineno">352</tt> <a class="py-toggle" href="#" id="captureOutput-toggle" onclick="return toggle('captureOutput');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#captureOutput">captureOutput</a><tt class="py-op">(</tt><tt class="py-param">callable</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
515
</div><div id="captureOutput-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="captureOutput-expanded"><a name="L353"></a><tt class="py-lineno">353</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
516
<a name="L354"></a><tt class="py-lineno">354</tt> <tt class="py-line"><tt class="py-docstring"> Captures the output (stdout, stderr) of a function or a method.</tt> </tt>
517
<a name="L355"></a><tt class="py-lineno">355</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
518
<a name="L356"></a><tt class="py-lineno">356</tt> <tt class="py-line"><tt class="py-docstring"> Some of our functions don't do anything other than just print output. We</tt> </tt>
519
<a name="L357"></a><tt class="py-lineno">357</tt> <tt class="py-line"><tt class="py-docstring"> need a way to test these functions (at least nominally) but we don't want</tt> </tt>
520
<a name="L358"></a><tt class="py-lineno">358</tt> <tt class="py-line"><tt class="py-docstring"> any of the output spoiling the test suite output.</tt> </tt>
521
521
<a name="L359"></a><tt class="py-lineno">359</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
522
<a name="L360"></a><tt class="py-lineno">360</tt> <tt class="py-line"><tt class="py-docstring"> @note: This method assumes that C{callable} doesn't take any arguments</tt> </tt>
523
<a name="L361"></a><tt class="py-lineno">361</tt> <tt class="py-line"><tt class="py-docstring"> besides keyword argument C{fd} to specify the file descriptor.</tt> </tt>
522
<a name="L360"></a><tt class="py-lineno">360</tt> <tt class="py-line"><tt class="py-docstring"> This function just creates a dummy file descriptor that can be used as a</tt> </tt>
523
<a name="L361"></a><tt class="py-lineno">361</tt> <tt class="py-line"><tt class="py-docstring"> target by the callable function, rather than C{stdout} or C{stderr}.</tt> </tt>
524
524
<a name="L362"></a><tt class="py-lineno">362</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
525
<a name="L363"></a><tt class="py-lineno">363</tt> <tt class="py-line"><tt class="py-docstring"> @param callable: Callable function or method.</tt> </tt>
526
<a name="L364"></a><tt class="py-lineno">364</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
527
<a name="L365"></a><tt class="py-lineno">365</tt> <tt class="py-line"><tt class="py-docstring"> @return: Output of function, as one big string.</tt> </tt>
528
<a name="L366"></a><tt class="py-lineno">366</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
529
<a name="L367"></a><tt class="py-lineno">367</tt> <tt class="py-line"> <tt class="py-name">fd</tt> <tt class="py-op">=</tt> <tt class="py-name">StringIO</tt><tt class="py-op">(</tt><tt class="py-op">)</tt> </tt>
530
<a name="L368"></a><tt class="py-lineno">368</tt> <tt class="py-line"> <tt class="py-name">callable</tt><tt class="py-op">(</tt><tt class="py-name">fd</tt><tt class="py-op">=</tt><tt class="py-name">fd</tt><tt class="py-op">)</tt> </tt>
531
<a name="L369"></a><tt class="py-lineno">369</tt> <tt class="py-line"> <tt class="py-name">result</tt> <tt class="py-op">=</tt> <tt class="py-name">fd</tt><tt class="py-op">.</tt><tt class="py-name">getvalue</tt><tt class="py-op">(</tt><tt class="py-op">)</tt> </tt>
532
<a name="L370"></a><tt class="py-lineno">370</tt> <tt class="py-line"> <tt class="py-name">fd</tt><tt class="py-op">.</tt><tt class="py-name">close</tt><tt class="py-op">(</tt><tt class="py-op">)</tt> </tt>
533
<a name="L371"></a><tt class="py-lineno">371</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-name">result</tt> </tt>
534
</div><a name="L372"></a><tt class="py-lineno">372</tt> <tt class="py-line"> </tt>
535
<a name="L373"></a><tt class="py-lineno">373</tt> <tt class="py-line"> </tt>
536
<a name="L374"></a><tt class="py-lineno">374</tt> <tt class="py-line"><tt class="py-comment">#########################</tt> </tt>
537
<a name="L375"></a><tt class="py-lineno">375</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># _isPlatform() function</tt> </tt>
538
<a name="L376"></a><tt class="py-lineno">376</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">#########################</tt> </tt>
539
<a name="L377"></a><tt class="py-lineno">377</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
540
<a name="_isPlatform"></a><div id="_isPlatform-def"><a name="L378"></a><tt class="py-lineno">378</tt> <a class="py-toggle" href="#" id="_isPlatform-toggle" onclick="return toggle('_isPlatform');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#_isPlatform">_isPlatform</a><tt class="py-op">(</tt><tt class="py-param">name</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
541
</div><div id="_isPlatform-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="_isPlatform-expanded"><a name="L379"></a><tt class="py-lineno">379</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
542
<a name="L380"></a><tt class="py-lineno">380</tt> <tt class="py-line"><tt class="py-docstring"> Returns boolean indicating whether we're running on the indicated platform.</tt> </tt>
543
<a name="L381"></a><tt class="py-lineno">381</tt> <tt class="py-line"><tt class="py-docstring"> @param name: Platform name to check, currently one of "windows" or "macosx"</tt> </tt>
544
<a name="L382"></a><tt class="py-lineno">382</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
545
<a name="L383"></a><tt class="py-lineno">383</tt> <tt class="py-line"> <tt class="py-keyword">if</tt> <tt id="link-19" class="py-name"><a title="CedarBackup2.config.ExtendedAction.name
525
<a name="L363"></a><tt class="py-lineno">363</tt> <tt class="py-line"><tt class="py-docstring"> @note: This method assumes that C{callable} doesn't take any arguments</tt> </tt>
526
<a name="L364"></a><tt class="py-lineno">364</tt> <tt class="py-line"><tt class="py-docstring"> besides keyword argument C{fd} to specify the file descriptor.</tt> </tt>
527
<a name="L365"></a><tt class="py-lineno">365</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
528
<a name="L366"></a><tt class="py-lineno">366</tt> <tt class="py-line"><tt class="py-docstring"> @param callable: Callable function or method.</tt> </tt>
529
<a name="L367"></a><tt class="py-lineno">367</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
530
<a name="L368"></a><tt class="py-lineno">368</tt> <tt class="py-line"><tt class="py-docstring"> @return: Output of function, as one big string.</tt> </tt>
531
<a name="L369"></a><tt class="py-lineno">369</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
532
<a name="L370"></a><tt class="py-lineno">370</tt> <tt class="py-line"> <tt class="py-name">fd</tt> <tt class="py-op">=</tt> <tt class="py-name">StringIO</tt><tt class="py-op">(</tt><tt class="py-op">)</tt> </tt>
533
<a name="L371"></a><tt class="py-lineno">371</tt> <tt class="py-line"> <tt class="py-name">callable</tt><tt class="py-op">(</tt><tt class="py-name">fd</tt><tt class="py-op">=</tt><tt class="py-name">fd</tt><tt class="py-op">)</tt> </tt>
534
<a name="L372"></a><tt class="py-lineno">372</tt> <tt class="py-line"> <tt class="py-name">result</tt> <tt class="py-op">=</tt> <tt class="py-name">fd</tt><tt class="py-op">.</tt><tt class="py-name">getvalue</tt><tt class="py-op">(</tt><tt class="py-op">)</tt> </tt>
535
<a name="L373"></a><tt class="py-lineno">373</tt> <tt class="py-line"> <tt class="py-name">fd</tt><tt class="py-op">.</tt><tt class="py-name">close</tt><tt class="py-op">(</tt><tt class="py-op">)</tt> </tt>
536
<a name="L374"></a><tt class="py-lineno">374</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-name">result</tt> </tt>
537
</div><a name="L375"></a><tt class="py-lineno">375</tt> <tt class="py-line"> </tt>
538
<a name="L376"></a><tt class="py-lineno">376</tt> <tt class="py-line"> </tt>
539
<a name="L377"></a><tt class="py-lineno">377</tt> <tt class="py-line"><tt class="py-comment">#########################</tt> </tt>
540
<a name="L378"></a><tt class="py-lineno">378</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># _isPlatform() function</tt> </tt>
541
<a name="L379"></a><tt class="py-lineno">379</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">#########################</tt> </tt>
542
<a name="L380"></a><tt class="py-lineno">380</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
543
<a name="_isPlatform"></a><div id="_isPlatform-def"><a name="L381"></a><tt class="py-lineno">381</tt> <a class="py-toggle" href="#" id="_isPlatform-toggle" onclick="return toggle('_isPlatform');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#_isPlatform">_isPlatform</a><tt class="py-op">(</tt><tt class="py-param">name</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
544
</div><div id="_isPlatform-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="_isPlatform-expanded"><a name="L382"></a><tt class="py-lineno">382</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
545
<a name="L383"></a><tt class="py-lineno">383</tt> <tt class="py-line"><tt class="py-docstring"> Returns boolean indicating whether we're running on the indicated platform.</tt> </tt>
546
<a name="L384"></a><tt class="py-lineno">384</tt> <tt class="py-line"><tt class="py-docstring"> @param name: Platform name to check, currently one of "windows" or "macosx"</tt> </tt>
547
<a name="L385"></a><tt class="py-lineno">385</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
548
<a name="L386"></a><tt class="py-lineno">386</tt> <tt class="py-line"> <tt class="py-keyword">if</tt> <tt id="link-19" class="py-name"><a title="CedarBackup2.config.ExtendedAction.name
546
549
CedarBackup2.config.LocalPeer.name
547
550
CedarBackup2.config.RemotePeer.name
548
551
CedarBackup2.peer.LocalPeer.name
549
552
CedarBackup2.peer.RemotePeer.name
550
553
CedarBackup2.util.DirectedGraph.name" class="py-name" href="#" onclick="return doclink('link-19', 'name', 'link-12');">name</a></tt> <tt class="py-op">==</tt> <tt class="py-string">"windows"</tt><tt class="py-op">:</tt> </tt>
551
<a name="L384"></a><tt class="py-lineno">384</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt id="link-20" class="py-name"><a title="CedarBackup2.util.Diagnostics.platform" class="py-name" href="#" onclick="return doclink('link-20', 'platform', 'link-0');">platform</a></tt><tt class="py-op">.</tt><tt id="link-21" class="py-name"><a title="CedarBackup2.util.Diagnostics.platform" class="py-name" href="#" onclick="return doclink('link-21', 'platform', 'link-0');">platform</a></tt><tt class="py-op">(</tt><tt class="py-name">True</tt><tt class="py-op">,</tt> <tt class="py-name">True</tt><tt class="py-op">)</tt><tt class="py-op">.</tt><tt class="py-name">startswith</tt><tt class="py-op">(</tt><tt class="py-string">"Windows"</tt><tt class="py-op">)</tt> </tt>
552
<a name="L385"></a><tt class="py-lineno">385</tt> <tt class="py-line"> <tt class="py-keyword">elif</tt> <tt id="link-22" class="py-name"><a title="CedarBackup2.config.ExtendedAction.name
554
<a name="L387"></a><tt class="py-lineno">387</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt id="link-20" class="py-name"><a title="CedarBackup2.util.Diagnostics.platform" class="py-name" href="#" onclick="return doclink('link-20', 'platform', 'link-0');">platform</a></tt><tt class="py-op">.</tt><tt id="link-21" class="py-name"><a title="CedarBackup2.util.Diagnostics.platform" class="py-name" href="#" onclick="return doclink('link-21', 'platform', 'link-0');">platform</a></tt><tt class="py-op">(</tt><tt class="py-name">True</tt><tt class="py-op">,</tt> <tt class="py-name">True</tt><tt class="py-op">)</tt><tt class="py-op">.</tt><tt class="py-name">startswith</tt><tt class="py-op">(</tt><tt class="py-string">"Windows"</tt><tt class="py-op">)</tt> </tt>
555
<a name="L388"></a><tt class="py-lineno">388</tt> <tt class="py-line"> <tt class="py-keyword">elif</tt> <tt id="link-22" class="py-name"><a title="CedarBackup2.config.ExtendedAction.name
553
556
CedarBackup2.config.LocalPeer.name
554
557
CedarBackup2.config.RemotePeer.name
555
558
CedarBackup2.peer.LocalPeer.name
556
559
CedarBackup2.peer.RemotePeer.name
557
560
CedarBackup2.util.DirectedGraph.name" class="py-name" href="#" onclick="return doclink('link-22', 'name', 'link-12');">name</a></tt> <tt class="py-op">==</tt> <tt class="py-string">"macosx"</tt><tt class="py-op">:</tt> </tt>
558
<a name="L386"></a><tt class="py-lineno">386</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-name">sys</tt><tt class="py-op">.</tt><tt id="link-23" class="py-name"><a title="CedarBackup2.util.Diagnostics.platform" class="py-name" href="#" onclick="return doclink('link-23', 'platform', 'link-0');">platform</a></tt> <tt class="py-op">==</tt> <tt class="py-string">"darwin"</tt> </tt>
559
<a name="L387"></a><tt class="py-lineno">387</tt> <tt class="py-line"> <tt class="py-keyword">else</tt><tt class="py-op">:</tt> </tt>
560
<a name="L388"></a><tt class="py-lineno">388</tt> <tt class="py-line"> <tt class="py-keyword">raise</tt> <tt class="py-name">ValueError</tt><tt class="py-op">(</tt><tt class="py-string">"Unknown platform [%s]."</tt> <tt class="py-op">%</tt> <tt id="link-24" class="py-name"><a title="CedarBackup2.config.ExtendedAction.name
561
<a name="L389"></a><tt class="py-lineno">389</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-name">sys</tt><tt class="py-op">.</tt><tt id="link-23" class="py-name"><a title="CedarBackup2.util.Diagnostics.platform" class="py-name" href="#" onclick="return doclink('link-23', 'platform', 'link-0');">platform</a></tt> <tt class="py-op">==</tt> <tt class="py-string">"darwin"</tt> </tt>
562
<a name="L390"></a><tt class="py-lineno">390</tt> <tt class="py-line"> <tt class="py-keyword">else</tt><tt class="py-op">:</tt> </tt>
563
<a name="L391"></a><tt class="py-lineno">391</tt> <tt class="py-line"> <tt class="py-keyword">raise</tt> <tt class="py-name">ValueError</tt><tt class="py-op">(</tt><tt class="py-string">"Unknown platform [%s]."</tt> <tt class="py-op">%</tt> <tt id="link-24" class="py-name"><a title="CedarBackup2.config.ExtendedAction.name
561
564
CedarBackup2.config.LocalPeer.name
562
565
CedarBackup2.config.RemotePeer.name
563
566
CedarBackup2.peer.LocalPeer.name
564
567
CedarBackup2.peer.RemotePeer.name
565
568
CedarBackup2.util.DirectedGraph.name" class="py-name" href="#" onclick="return doclink('link-24', 'name', 'link-12');">name</a></tt><tt class="py-op">)</tt> </tt>
566
</div><a name="L389"></a><tt class="py-lineno">389</tt> <tt class="py-line"> </tt>
567
<a name="L390"></a><tt class="py-lineno">390</tt> <tt class="py-line"> </tt>
568
<a name="L391"></a><tt class="py-lineno">391</tt> <tt class="py-line"><tt class="py-comment">############################</tt> </tt>
569
<a name="L392"></a><tt class="py-lineno">392</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># platformMacOsX() function</tt> </tt>
570
<a name="L393"></a><tt class="py-lineno">393</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">############################</tt> </tt>
571
<a name="L394"></a><tt class="py-lineno">394</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
572
<a name="platformMacOsX"></a><div id="platformMacOsX-def"><a name="L395"></a><tt class="py-lineno">395</tt> <a class="py-toggle" href="#" id="platformMacOsX-toggle" onclick="return toggle('platformMacOsX');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#platformMacOsX">platformMacOsX</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
573
</div><div id="platformMacOsX-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="platformMacOsX-expanded"><a name="L396"></a><tt class="py-lineno">396</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
574
<a name="L397"></a><tt class="py-lineno">397</tt> <tt class="py-line"><tt class="py-docstring"> Returns boolean indicating whether this is the Mac OS X platform.</tt> </tt>
575
<a name="L398"></a><tt class="py-lineno">398</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
576
<a name="L399"></a><tt class="py-lineno">399</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt id="link-25" class="py-name" targets="Function CedarBackup2.testutil._isPlatform()=CedarBackup2.testutil-module.html#_isPlatform"><a title="CedarBackup2.testutil._isPlatform" class="py-name" href="#" onclick="return doclink('link-25', '_isPlatform', 'link-25');">_isPlatform</a></tt><tt class="py-op">(</tt><tt class="py-string">"macosx"</tt><tt class="py-op">)</tt> </tt>
577
</div><a name="L400"></a><tt class="py-lineno">400</tt> <tt class="py-line"> </tt>
578
<a name="L401"></a><tt class="py-lineno">401</tt> <tt class="py-line"> </tt>
579
<a name="L402"></a><tt class="py-lineno">402</tt> <tt class="py-line"><tt class="py-comment">#############################</tt> </tt>
580
<a name="L403"></a><tt class="py-lineno">403</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># platformWindows() function</tt> </tt>
581
<a name="L404"></a><tt class="py-lineno">404</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">#############################</tt> </tt>
582
<a name="L405"></a><tt class="py-lineno">405</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
583
<a name="platformWindows"></a><div id="platformWindows-def"><a name="L406"></a><tt class="py-lineno">406</tt> <a class="py-toggle" href="#" id="platformWindows-toggle" onclick="return toggle('platformWindows');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#platformWindows">platformWindows</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
584
</div><div id="platformWindows-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="platformWindows-expanded"><a name="L407"></a><tt class="py-lineno">407</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
585
<a name="L408"></a><tt class="py-lineno">408</tt> <tt class="py-line"><tt class="py-docstring"> Returns boolean indicating whether this is the Windows platform.</tt> </tt>
586
<a name="L409"></a><tt class="py-lineno">409</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
587
<a name="L410"></a><tt class="py-lineno">410</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt id="link-26" class="py-name"><a title="CedarBackup2.testutil._isPlatform" class="py-name" href="#" onclick="return doclink('link-26', '_isPlatform', 'link-25');">_isPlatform</a></tt><tt class="py-op">(</tt><tt class="py-string">"windows"</tt><tt class="py-op">)</tt> </tt>
588
</div><a name="L411"></a><tt class="py-lineno">411</tt> <tt class="py-line"> </tt>
589
<a name="L412"></a><tt class="py-lineno">412</tt> <tt class="py-line"> </tt>
590
<a name="L413"></a><tt class="py-lineno">413</tt> <tt class="py-line"><tt class="py-comment">###################################</tt> </tt>
591
<a name="L414"></a><tt class="py-lineno">414</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># platformSupportsLinks() function</tt> </tt>
592
<a name="L415"></a><tt class="py-lineno">415</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">###################################</tt> </tt>
593
<a name="L416"></a><tt class="py-lineno">416</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
594
<a name="platformSupportsLinks"></a><div id="platformSupportsLinks-def"><a name="L417"></a><tt class="py-lineno">417</tt> <a class="py-toggle" href="#" id="platformSupportsLinks-toggle" onclick="return toggle('platformSupportsLinks');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#platformSupportsLinks">platformSupportsLinks</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
595
</div><div id="platformSupportsLinks-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="platformSupportsLinks-expanded"><a name="L418"></a><tt class="py-lineno">418</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
596
<a name="L419"></a><tt class="py-lineno">419</tt> <tt class="py-line"><tt class="py-docstring"> Returns boolean indicating whether the platform supports soft-links.</tt> </tt>
597
<a name="L420"></a><tt class="py-lineno">420</tt> <tt class="py-line"><tt class="py-docstring"> Some platforms, like Windows, do not support links, and tests need to take</tt> </tt>
598
<a name="L421"></a><tt class="py-lineno">421</tt> <tt class="py-line"><tt class="py-docstring"> this into account.</tt> </tt>
599
<a name="L422"></a><tt class="py-lineno">422</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
600
<a name="L423"></a><tt class="py-lineno">423</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-keyword">not</tt> <tt id="link-27" class="py-name" targets="Function CedarBackup2.testutil.platformWindows()=CedarBackup2.testutil-module.html#platformWindows"><a title="CedarBackup2.testutil.platformWindows" class="py-name" href="#" onclick="return doclink('link-27', 'platformWindows', 'link-27');">platformWindows</a></tt><tt class="py-op">(</tt><tt class="py-op">)</tt> </tt>
601
</div><a name="L424"></a><tt class="py-lineno">424</tt> <tt class="py-line"> </tt>
602
<a name="L425"></a><tt class="py-lineno">425</tt> <tt class="py-line"> </tt>
603
<a name="L426"></a><tt class="py-lineno">426</tt> <tt class="py-line"><tt class="py-comment">#########################################</tt> </tt>
604
<a name="L427"></a><tt class="py-lineno">427</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># platformSupportsPermissions() function</tt> </tt>
605
<a name="L428"></a><tt class="py-lineno">428</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">#########################################</tt> </tt>
606
<a name="L429"></a><tt class="py-lineno">429</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
607
<a name="platformSupportsPermissions"></a><div id="platformSupportsPermissions-def"><a name="L430"></a><tt class="py-lineno">430</tt> <a class="py-toggle" href="#" id="platformSupportsPermissions-toggle" onclick="return toggle('platformSupportsPermissions');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#platformSupportsPermissions">platformSupportsPermissions</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
608
</div><div id="platformSupportsPermissions-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="platformSupportsPermissions-expanded"><a name="L431"></a><tt class="py-lineno">431</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
609
<a name="L432"></a><tt class="py-lineno">432</tt> <tt class="py-line"><tt class="py-docstring"> Returns boolean indicating whether the platform supports UNIX-style file permissions.</tt> </tt>
610
<a name="L433"></a><tt class="py-lineno">433</tt> <tt class="py-line"><tt class="py-docstring"> Some platforms, like Windows, do not support permissions, and tests need to take</tt> </tt>
611
<a name="L434"></a><tt class="py-lineno">434</tt> <tt class="py-line"><tt class="py-docstring"> this into account.</tt> </tt>
612
<a name="L435"></a><tt class="py-lineno">435</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
613
<a name="L436"></a><tt class="py-lineno">436</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-keyword">not</tt> <tt id="link-28" class="py-name"><a title="CedarBackup2.testutil.platformWindows" class="py-name" href="#" onclick="return doclink('link-28', 'platformWindows', 'link-27');">platformWindows</a></tt><tt class="py-op">(</tt><tt class="py-op">)</tt> </tt>
614
</div><a name="L437"></a><tt class="py-lineno">437</tt> <tt class="py-line"> </tt>
615
<a name="L438"></a><tt class="py-lineno">438</tt> <tt class="py-line"> </tt>
616
<a name="L439"></a><tt class="py-lineno">439</tt> <tt class="py-line"><tt class="py-comment">########################################</tt> </tt>
617
<a name="L440"></a><tt class="py-lineno">440</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># platformRequiresBinaryRead() function</tt> </tt>
618
<a name="L441"></a><tt class="py-lineno">441</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">########################################</tt> </tt>
619
<a name="L442"></a><tt class="py-lineno">442</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
620
<a name="platformRequiresBinaryRead"></a><div id="platformRequiresBinaryRead-def"><a name="L443"></a><tt class="py-lineno">443</tt> <a class="py-toggle" href="#" id="platformRequiresBinaryRead-toggle" onclick="return toggle('platformRequiresBinaryRead');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#platformRequiresBinaryRead">platformRequiresBinaryRead</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
621
</div><div id="platformRequiresBinaryRead-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="platformRequiresBinaryRead-expanded"><a name="L444"></a><tt class="py-lineno">444</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
622
<a name="L445"></a><tt class="py-lineno">445</tt> <tt class="py-line"><tt class="py-docstring"> Returns boolean indicating whether the platform requires binary reads.</tt> </tt>
623
<a name="L446"></a><tt class="py-lineno">446</tt> <tt class="py-line"><tt class="py-docstring"> Some platforms, like Windows, require a special flag to read binary data</tt> </tt>
624
<a name="L447"></a><tt class="py-lineno">447</tt> <tt class="py-line"><tt class="py-docstring"> from files.</tt> </tt>
625
<a name="L448"></a><tt class="py-lineno">448</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
626
<a name="L449"></a><tt class="py-lineno">449</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt id="link-29" class="py-name"><a title="CedarBackup2.testutil.platformWindows" class="py-name" href="#" onclick="return doclink('link-29', 'platformWindows', 'link-27');">platformWindows</a></tt><tt class="py-op">(</tt><tt class="py-op">)</tt> </tt>
627
</div><a name="L450"></a><tt class="py-lineno">450</tt> <tt class="py-line"> </tt>
628
<a name="L451"></a><tt class="py-lineno">451</tt> <tt class="py-line"> </tt>
629
<a name="L452"></a><tt class="py-lineno">452</tt> <tt class="py-line"><tt class="py-comment">#############################</tt> </tt>
630
<a name="L453"></a><tt class="py-lineno">453</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># platformHasEcho() function</tt> </tt>
631
<a name="L454"></a><tt class="py-lineno">454</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">#############################</tt> </tt>
632
<a name="L455"></a><tt class="py-lineno">455</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
633
<a name="platformHasEcho"></a><div id="platformHasEcho-def"><a name="L456"></a><tt class="py-lineno">456</tt> <a class="py-toggle" href="#" id="platformHasEcho-toggle" onclick="return toggle('platformHasEcho');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#platformHasEcho">platformHasEcho</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
634
</div><div id="platformHasEcho-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="platformHasEcho-expanded"><a name="L457"></a><tt class="py-lineno">457</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
635
<a name="L458"></a><tt class="py-lineno">458</tt> <tt class="py-line"><tt class="py-docstring"> Returns boolean indicating whether the platform has a sensible echo command.</tt> </tt>
636
<a name="L459"></a><tt class="py-lineno">459</tt> <tt class="py-line"><tt class="py-docstring"> On some platforms, like Windows, echo doesn't really work for tests.</tt> </tt>
637
<a name="L460"></a><tt class="py-lineno">460</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
638
<a name="L461"></a><tt class="py-lineno">461</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-keyword">not</tt> <tt id="link-30" class="py-name"><a title="CedarBackup2.testutil.platformWindows" class="py-name" href="#" onclick="return doclink('link-30', 'platformWindows', 'link-27');">platformWindows</a></tt><tt class="py-op">(</tt><tt class="py-op">)</tt> </tt>
639
</div><a name="L462"></a><tt class="py-lineno">462</tt> <tt class="py-line"> </tt>
640
<a name="L463"></a><tt class="py-lineno">463</tt> <tt class="py-line"> </tt>
641
<a name="L464"></a><tt class="py-lineno">464</tt> <tt class="py-line"><tt class="py-comment">###########################</tt> </tt>
642
<a name="L465"></a><tt class="py-lineno">465</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># runningAsRoot() function</tt> </tt>
643
<a name="L466"></a><tt class="py-lineno">466</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">###########################</tt> </tt>
644
<a name="L467"></a><tt class="py-lineno">467</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
645
<a name="runningAsRoot"></a><div id="runningAsRoot-def"><a name="L468"></a><tt class="py-lineno">468</tt> <a class="py-toggle" href="#" id="runningAsRoot-toggle" onclick="return toggle('runningAsRoot');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#runningAsRoot">runningAsRoot</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
646
</div><div id="runningAsRoot-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="runningAsRoot-expanded"><a name="L469"></a><tt class="py-lineno">469</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
647
<a name="L470"></a><tt class="py-lineno">470</tt> <tt class="py-line"><tt class="py-docstring"> Returns boolean indicating whether the effective user id is root.</tt> </tt>
648
<a name="L471"></a><tt class="py-lineno">471</tt> <tt class="py-line"><tt class="py-docstring"> This is always true on platforms that have no concept of root, like Windows.</tt> </tt>
649
<a name="L472"></a><tt class="py-lineno">472</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
650
<a name="L473"></a><tt class="py-lineno">473</tt> <tt class="py-line"> <tt class="py-keyword">if</tt> <tt id="link-31" class="py-name"><a title="CedarBackup2.testutil.platformWindows" class="py-name" href="#" onclick="return doclink('link-31', 'platformWindows', 'link-27');">platformWindows</a></tt><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
651
<a name="L474"></a><tt class="py-lineno">474</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-name">True</tt> </tt>
652
<a name="L475"></a><tt class="py-lineno">475</tt> <tt class="py-line"> <tt class="py-keyword">else</tt><tt class="py-op">:</tt> </tt>
653
<a name="L476"></a><tt class="py-lineno">476</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-name">os</tt><tt class="py-op">.</tt><tt class="py-name">geteuid</tt><tt class="py-op">(</tt><tt class="py-op">)</tt> <tt class="py-op">==</tt> <tt class="py-number">0</tt> </tt>
654
</div><a name="L477"></a><tt class="py-lineno">477</tt> <tt class="py-line"> </tt>
655
<a name="L478"></a><tt class="py-lineno">478</tt> <tt class="py-line"> </tt>
656
<a name="L479"></a><tt class="py-lineno">479</tt> <tt class="py-line"><tt class="py-comment">##############################</tt> </tt>
657
<a name="L480"></a><tt class="py-lineno">480</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># availableLocales() function</tt> </tt>
658
<a name="L481"></a><tt class="py-lineno">481</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">##############################</tt> </tt>
659
<a name="L482"></a><tt class="py-lineno">482</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
660
<a name="availableLocales"></a><div id="availableLocales-def"><a name="L483"></a><tt class="py-lineno">483</tt> <a class="py-toggle" href="#" id="availableLocales-toggle" onclick="return toggle('availableLocales');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#availableLocales">availableLocales</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
661
</div><div id="availableLocales-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="availableLocales-expanded"><a name="L484"></a><tt class="py-lineno">484</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
662
<a name="L485"></a><tt class="py-lineno">485</tt> <tt class="py-line"><tt class="py-docstring"> Returns a list of available locales on the system</tt> </tt>
663
<a name="L486"></a><tt class="py-lineno">486</tt> <tt class="py-line"><tt class="py-docstring"> @return: List of string locale names</tt> </tt>
664
<a name="L487"></a><tt class="py-lineno">487</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
665
<a name="L488"></a><tt class="py-lineno">488</tt> <tt class="py-line"> <tt class="py-name">locales</tt> <tt class="py-op">=</tt> <tt class="py-op">[</tt><tt class="py-op">]</tt> </tt>
666
<a name="L489"></a><tt class="py-lineno">489</tt> <tt class="py-line"> <tt id="link-32" class="py-name" targets="Variable CedarBackup2.cli.Options.output=CedarBackup2.cli.Options-class.html#output"><a title="CedarBackup2.cli.Options.output" class="py-name" href="#" onclick="return doclink('link-32', 'output', 'link-32');">output</a></tt> <tt class="py-op">=</tt> <tt id="link-33" class="py-name"><a title="CedarBackup2.util.executeCommand" class="py-name" href="#" onclick="return doclink('link-33', 'executeCommand', 'link-4');">executeCommand</a></tt><tt class="py-op">(</tt><tt class="py-op">[</tt><tt class="py-string">"locale"</tt><tt class="py-op">]</tt><tt class="py-op">,</tt> <tt class="py-op">[</tt> <tt class="py-string">"-a"</tt><tt class="py-op">,</tt> <tt class="py-op">]</tt><tt class="py-op">,</tt> <tt class="py-name">returnOutput</tt><tt class="py-op">=</tt><tt class="py-name">True</tt><tt class="py-op">,</tt> <tt class="py-name">ignoreStderr</tt><tt class="py-op">=</tt><tt class="py-name">True</tt><tt class="py-op">)</tt><tt class="py-op">[</tt><tt class="py-number">1</tt><tt class="py-op">]</tt> </tt>
667
<a name="L490"></a><tt class="py-lineno">490</tt> <tt class="py-line"> <tt class="py-keyword">for</tt> <tt class="py-name">line</tt> <tt class="py-keyword">in</tt> <tt id="link-34" class="py-name"><a title="CedarBackup2.cli.Options.output" class="py-name" href="#" onclick="return doclink('link-34', 'output', 'link-32');">output</a></tt><tt class="py-op">:</tt> </tt>
668
<a name="L491"></a><tt class="py-lineno">491</tt> <tt class="py-line"> <tt class="py-name">locales</tt><tt class="py-op">.</tt><tt id="link-35" class="py-name" targets="Method CedarBackup2.util.AbsolutePathList.append()=CedarBackup2.util.AbsolutePathList-class.html#append,Method CedarBackup2.util.ObjectTypeList.append()=CedarBackup2.util.ObjectTypeList-class.html#append,Method CedarBackup2.util.RegexList.append()=CedarBackup2.util.RegexList-class.html#append,Method CedarBackup2.util.RegexMatchList.append()=CedarBackup2.util.RegexMatchList-class.html#append,Method CedarBackup2.util.RestrictedContentList.append()=CedarBackup2.util.RestrictedContentList-class.html#append"><a title="CedarBackup2.util.AbsolutePathList.append
569
</div><a name="L392"></a><tt class="py-lineno">392</tt> <tt class="py-line"> </tt>
570
<a name="L393"></a><tt class="py-lineno">393</tt> <tt class="py-line"> </tt>
571
<a name="L394"></a><tt class="py-lineno">394</tt> <tt class="py-line"><tt class="py-comment">############################</tt> </tt>
572
<a name="L395"></a><tt class="py-lineno">395</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># platformMacOsX() function</tt> </tt>
573
<a name="L396"></a><tt class="py-lineno">396</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">############################</tt> </tt>
574
<a name="L397"></a><tt class="py-lineno">397</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
575
<a name="platformMacOsX"></a><div id="platformMacOsX-def"><a name="L398"></a><tt class="py-lineno">398</tt> <a class="py-toggle" href="#" id="platformMacOsX-toggle" onclick="return toggle('platformMacOsX');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#platformMacOsX">platformMacOsX</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
576
</div><div id="platformMacOsX-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="platformMacOsX-expanded"><a name="L399"></a><tt class="py-lineno">399</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
577
<a name="L400"></a><tt class="py-lineno">400</tt> <tt class="py-line"><tt class="py-docstring"> Returns boolean indicating whether this is the Mac OS X platform.</tt> </tt>
578
<a name="L401"></a><tt class="py-lineno">401</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
579
<a name="L402"></a><tt class="py-lineno">402</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt id="link-25" class="py-name" targets="Function CedarBackup2.testutil._isPlatform()=CedarBackup2.testutil-module.html#_isPlatform"><a title="CedarBackup2.testutil._isPlatform" class="py-name" href="#" onclick="return doclink('link-25', '_isPlatform', 'link-25');">_isPlatform</a></tt><tt class="py-op">(</tt><tt class="py-string">"macosx"</tt><tt class="py-op">)</tt> </tt>
580
</div><a name="L403"></a><tt class="py-lineno">403</tt> <tt class="py-line"> </tt>
581
<a name="L404"></a><tt class="py-lineno">404</tt> <tt class="py-line"> </tt>
582
<a name="L405"></a><tt class="py-lineno">405</tt> <tt class="py-line"><tt class="py-comment">#############################</tt> </tt>
583
<a name="L406"></a><tt class="py-lineno">406</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># platformWindows() function</tt> </tt>
584
<a name="L407"></a><tt class="py-lineno">407</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">#############################</tt> </tt>
585
<a name="L408"></a><tt class="py-lineno">408</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
586
<a name="platformWindows"></a><div id="platformWindows-def"><a name="L409"></a><tt class="py-lineno">409</tt> <a class="py-toggle" href="#" id="platformWindows-toggle" onclick="return toggle('platformWindows');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#platformWindows">platformWindows</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
587
</div><div id="platformWindows-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="platformWindows-expanded"><a name="L410"></a><tt class="py-lineno">410</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
588
<a name="L411"></a><tt class="py-lineno">411</tt> <tt class="py-line"><tt class="py-docstring"> Returns boolean indicating whether this is the Windows platform.</tt> </tt>
589
<a name="L412"></a><tt class="py-lineno">412</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
590
<a name="L413"></a><tt class="py-lineno">413</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt id="link-26" class="py-name"><a title="CedarBackup2.testutil._isPlatform" class="py-name" href="#" onclick="return doclink('link-26', '_isPlatform', 'link-25');">_isPlatform</a></tt><tt class="py-op">(</tt><tt class="py-string">"windows"</tt><tt class="py-op">)</tt> </tt>
591
</div><a name="L414"></a><tt class="py-lineno">414</tt> <tt class="py-line"> </tt>
592
<a name="L415"></a><tt class="py-lineno">415</tt> <tt class="py-line"> </tt>
593
<a name="L416"></a><tt class="py-lineno">416</tt> <tt class="py-line"><tt class="py-comment">###################################</tt> </tt>
594
<a name="L417"></a><tt class="py-lineno">417</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># platformSupportsLinks() function</tt> </tt>
595
<a name="L418"></a><tt class="py-lineno">418</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">###################################</tt> </tt>
596
<a name="L419"></a><tt class="py-lineno">419</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
597
<a name="platformSupportsLinks"></a><div id="platformSupportsLinks-def"><a name="L420"></a><tt class="py-lineno">420</tt> <a class="py-toggle" href="#" id="platformSupportsLinks-toggle" onclick="return toggle('platformSupportsLinks');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#platformSupportsLinks">platformSupportsLinks</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
598
</div><div id="platformSupportsLinks-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="platformSupportsLinks-expanded"><a name="L421"></a><tt class="py-lineno">421</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
599
<a name="L422"></a><tt class="py-lineno">422</tt> <tt class="py-line"><tt class="py-docstring"> Returns boolean indicating whether the platform supports soft-links.</tt> </tt>
600
<a name="L423"></a><tt class="py-lineno">423</tt> <tt class="py-line"><tt class="py-docstring"> Some platforms, like Windows, do not support links, and tests need to take</tt> </tt>
601
<a name="L424"></a><tt class="py-lineno">424</tt> <tt class="py-line"><tt class="py-docstring"> this into account.</tt> </tt>
602
<a name="L425"></a><tt class="py-lineno">425</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
603
<a name="L426"></a><tt class="py-lineno">426</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-keyword">not</tt> <tt id="link-27" class="py-name" targets="Function CedarBackup2.testutil.platformWindows()=CedarBackup2.testutil-module.html#platformWindows"><a title="CedarBackup2.testutil.platformWindows" class="py-name" href="#" onclick="return doclink('link-27', 'platformWindows', 'link-27');">platformWindows</a></tt><tt class="py-op">(</tt><tt class="py-op">)</tt> </tt>
604
</div><a name="L427"></a><tt class="py-lineno">427</tt> <tt class="py-line"> </tt>
605
<a name="L428"></a><tt class="py-lineno">428</tt> <tt class="py-line"> </tt>
606
<a name="L429"></a><tt class="py-lineno">429</tt> <tt class="py-line"><tt class="py-comment">#########################################</tt> </tt>
607
<a name="L430"></a><tt class="py-lineno">430</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># platformSupportsPermissions() function</tt> </tt>
608
<a name="L431"></a><tt class="py-lineno">431</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">#########################################</tt> </tt>
609
<a name="L432"></a><tt class="py-lineno">432</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
610
<a name="platformSupportsPermissions"></a><div id="platformSupportsPermissions-def"><a name="L433"></a><tt class="py-lineno">433</tt> <a class="py-toggle" href="#" id="platformSupportsPermissions-toggle" onclick="return toggle('platformSupportsPermissions');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#platformSupportsPermissions">platformSupportsPermissions</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
611
</div><div id="platformSupportsPermissions-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="platformSupportsPermissions-expanded"><a name="L434"></a><tt class="py-lineno">434</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
612
<a name="L435"></a><tt class="py-lineno">435</tt> <tt class="py-line"><tt class="py-docstring"> Returns boolean indicating whether the platform supports UNIX-style file permissions.</tt> </tt>
613
<a name="L436"></a><tt class="py-lineno">436</tt> <tt class="py-line"><tt class="py-docstring"> Some platforms, like Windows, do not support permissions, and tests need to take</tt> </tt>
614
<a name="L437"></a><tt class="py-lineno">437</tt> <tt class="py-line"><tt class="py-docstring"> this into account.</tt> </tt>
615
<a name="L438"></a><tt class="py-lineno">438</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
616
<a name="L439"></a><tt class="py-lineno">439</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-keyword">not</tt> <tt id="link-28" class="py-name"><a title="CedarBackup2.testutil.platformWindows" class="py-name" href="#" onclick="return doclink('link-28', 'platformWindows', 'link-27');">platformWindows</a></tt><tt class="py-op">(</tt><tt class="py-op">)</tt> </tt>
617
</div><a name="L440"></a><tt class="py-lineno">440</tt> <tt class="py-line"> </tt>
618
<a name="L441"></a><tt class="py-lineno">441</tt> <tt class="py-line"> </tt>
619
<a name="L442"></a><tt class="py-lineno">442</tt> <tt class="py-line"><tt class="py-comment">########################################</tt> </tt>
620
<a name="L443"></a><tt class="py-lineno">443</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># platformRequiresBinaryRead() function</tt> </tt>
621
<a name="L444"></a><tt class="py-lineno">444</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">########################################</tt> </tt>
622
<a name="L445"></a><tt class="py-lineno">445</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
623
<a name="platformRequiresBinaryRead"></a><div id="platformRequiresBinaryRead-def"><a name="L446"></a><tt class="py-lineno">446</tt> <a class="py-toggle" href="#" id="platformRequiresBinaryRead-toggle" onclick="return toggle('platformRequiresBinaryRead');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#platformRequiresBinaryRead">platformRequiresBinaryRead</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
624
</div><div id="platformRequiresBinaryRead-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="platformRequiresBinaryRead-expanded"><a name="L447"></a><tt class="py-lineno">447</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
625
<a name="L448"></a><tt class="py-lineno">448</tt> <tt class="py-line"><tt class="py-docstring"> Returns boolean indicating whether the platform requires binary reads.</tt> </tt>
626
<a name="L449"></a><tt class="py-lineno">449</tt> <tt class="py-line"><tt class="py-docstring"> Some platforms, like Windows, require a special flag to read binary data</tt> </tt>
627
<a name="L450"></a><tt class="py-lineno">450</tt> <tt class="py-line"><tt class="py-docstring"> from files.</tt> </tt>
628
<a name="L451"></a><tt class="py-lineno">451</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
629
<a name="L452"></a><tt class="py-lineno">452</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt id="link-29" class="py-name"><a title="CedarBackup2.testutil.platformWindows" class="py-name" href="#" onclick="return doclink('link-29', 'platformWindows', 'link-27');">platformWindows</a></tt><tt class="py-op">(</tt><tt class="py-op">)</tt> </tt>
630
</div><a name="L453"></a><tt class="py-lineno">453</tt> <tt class="py-line"> </tt>
631
<a name="L454"></a><tt class="py-lineno">454</tt> <tt class="py-line"> </tt>
632
<a name="L455"></a><tt class="py-lineno">455</tt> <tt class="py-line"><tt class="py-comment">#############################</tt> </tt>
633
<a name="L456"></a><tt class="py-lineno">456</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># platformHasEcho() function</tt> </tt>
634
<a name="L457"></a><tt class="py-lineno">457</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">#############################</tt> </tt>
635
<a name="L458"></a><tt class="py-lineno">458</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
636
<a name="platformHasEcho"></a><div id="platformHasEcho-def"><a name="L459"></a><tt class="py-lineno">459</tt> <a class="py-toggle" href="#" id="platformHasEcho-toggle" onclick="return toggle('platformHasEcho');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#platformHasEcho">platformHasEcho</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
637
</div><div id="platformHasEcho-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="platformHasEcho-expanded"><a name="L460"></a><tt class="py-lineno">460</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
638
<a name="L461"></a><tt class="py-lineno">461</tt> <tt class="py-line"><tt class="py-docstring"> Returns boolean indicating whether the platform has a sensible echo command.</tt> </tt>
639
<a name="L462"></a><tt class="py-lineno">462</tt> <tt class="py-line"><tt class="py-docstring"> On some platforms, like Windows, echo doesn't really work for tests.</tt> </tt>
640
<a name="L463"></a><tt class="py-lineno">463</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
641
<a name="L464"></a><tt class="py-lineno">464</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-keyword">not</tt> <tt id="link-30" class="py-name"><a title="CedarBackup2.testutil.platformWindows" class="py-name" href="#" onclick="return doclink('link-30', 'platformWindows', 'link-27');">platformWindows</a></tt><tt class="py-op">(</tt><tt class="py-op">)</tt> </tt>
642
</div><a name="L465"></a><tt class="py-lineno">465</tt> <tt class="py-line"> </tt>
643
<a name="L466"></a><tt class="py-lineno">466</tt> <tt class="py-line"> </tt>
644
<a name="L467"></a><tt class="py-lineno">467</tt> <tt class="py-line"><tt class="py-comment">###########################</tt> </tt>
645
<a name="L468"></a><tt class="py-lineno">468</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># runningAsRoot() function</tt> </tt>
646
<a name="L469"></a><tt class="py-lineno">469</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">###########################</tt> </tt>
647
<a name="L470"></a><tt class="py-lineno">470</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
648
<a name="runningAsRoot"></a><div id="runningAsRoot-def"><a name="L471"></a><tt class="py-lineno">471</tt> <a class="py-toggle" href="#" id="runningAsRoot-toggle" onclick="return toggle('runningAsRoot');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#runningAsRoot">runningAsRoot</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
649
</div><div id="runningAsRoot-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="runningAsRoot-expanded"><a name="L472"></a><tt class="py-lineno">472</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
650
<a name="L473"></a><tt class="py-lineno">473</tt> <tt class="py-line"><tt class="py-docstring"> Returns boolean indicating whether the effective user id is root.</tt> </tt>
651
<a name="L474"></a><tt class="py-lineno">474</tt> <tt class="py-line"><tt class="py-docstring"> This is always true on platforms that have no concept of root, like Windows.</tt> </tt>
652
<a name="L475"></a><tt class="py-lineno">475</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
653
<a name="L476"></a><tt class="py-lineno">476</tt> <tt class="py-line"> <tt class="py-keyword">if</tt> <tt id="link-31" class="py-name"><a title="CedarBackup2.testutil.platformWindows" class="py-name" href="#" onclick="return doclink('link-31', 'platformWindows', 'link-27');">platformWindows</a></tt><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
654
<a name="L477"></a><tt class="py-lineno">477</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-name">True</tt> </tt>
655
<a name="L478"></a><tt class="py-lineno">478</tt> <tt class="py-line"> <tt class="py-keyword">else</tt><tt class="py-op">:</tt> </tt>
656
<a name="L479"></a><tt class="py-lineno">479</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-name">os</tt><tt class="py-op">.</tt><tt class="py-name">geteuid</tt><tt class="py-op">(</tt><tt class="py-op">)</tt> <tt class="py-op">==</tt> <tt class="py-number">0</tt> </tt>
657
</div><a name="L480"></a><tt class="py-lineno">480</tt> <tt class="py-line"> </tt>
658
<a name="L481"></a><tt class="py-lineno">481</tt> <tt class="py-line"> </tt>
659
<a name="L482"></a><tt class="py-lineno">482</tt> <tt class="py-line"><tt class="py-comment">##############################</tt> </tt>
660
<a name="L483"></a><tt class="py-lineno">483</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># availableLocales() function</tt> </tt>
661
<a name="L484"></a><tt class="py-lineno">484</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">##############################</tt> </tt>
662
<a name="L485"></a><tt class="py-lineno">485</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
663
<a name="availableLocales"></a><div id="availableLocales-def"><a name="L486"></a><tt class="py-lineno">486</tt> <a class="py-toggle" href="#" id="availableLocales-toggle" onclick="return toggle('availableLocales');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#availableLocales">availableLocales</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
664
</div><div id="availableLocales-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="availableLocales-expanded"><a name="L487"></a><tt class="py-lineno">487</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
665
<a name="L488"></a><tt class="py-lineno">488</tt> <tt class="py-line"><tt class="py-docstring"> Returns a list of available locales on the system</tt> </tt>
666
<a name="L489"></a><tt class="py-lineno">489</tt> <tt class="py-line"><tt class="py-docstring"> @return: List of string locale names</tt> </tt>
667
<a name="L490"></a><tt class="py-lineno">490</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
668
<a name="L491"></a><tt class="py-lineno">491</tt> <tt class="py-line"> <tt class="py-name">locales</tt> <tt class="py-op">=</tt> <tt class="py-op">[</tt><tt class="py-op">]</tt> </tt>
669
<a name="L492"></a><tt class="py-lineno">492</tt> <tt class="py-line"> <tt id="link-32" class="py-name" targets="Variable CedarBackup2.cli.Options.output=CedarBackup2.cli.Options-class.html#output"><a title="CedarBackup2.cli.Options.output" class="py-name" href="#" onclick="return doclink('link-32', 'output', 'link-32');">output</a></tt> <tt class="py-op">=</tt> <tt id="link-33" class="py-name"><a title="CedarBackup2.util.executeCommand" class="py-name" href="#" onclick="return doclink('link-33', 'executeCommand', 'link-4');">executeCommand</a></tt><tt class="py-op">(</tt><tt class="py-op">[</tt><tt class="py-string">"locale"</tt><tt class="py-op">]</tt><tt class="py-op">,</tt> <tt class="py-op">[</tt> <tt class="py-string">"-a"</tt><tt class="py-op">,</tt> <tt class="py-op">]</tt><tt class="py-op">,</tt> <tt class="py-name">returnOutput</tt><tt class="py-op">=</tt><tt class="py-name">True</tt><tt class="py-op">,</tt> <tt class="py-name">ignoreStderr</tt><tt class="py-op">=</tt><tt class="py-name">True</tt><tt class="py-op">)</tt><tt class="py-op">[</tt><tt class="py-number">1</tt><tt class="py-op">]</tt> </tt>
670
<a name="L493"></a><tt class="py-lineno">493</tt> <tt class="py-line"> <tt class="py-keyword">for</tt> <tt class="py-name">line</tt> <tt class="py-keyword">in</tt> <tt id="link-34" class="py-name"><a title="CedarBackup2.cli.Options.output" class="py-name" href="#" onclick="return doclink('link-34', 'output', 'link-32');">output</a></tt><tt class="py-op">:</tt> </tt>
671
<a name="L494"></a><tt class="py-lineno">494</tt> <tt class="py-line"> <tt class="py-name">locales</tt><tt class="py-op">.</tt><tt id="link-35" class="py-name" targets="Method CedarBackup2.util.AbsolutePathList.append()=CedarBackup2.util.AbsolutePathList-class.html#append,Method CedarBackup2.util.ObjectTypeList.append()=CedarBackup2.util.ObjectTypeList-class.html#append,Method CedarBackup2.util.RegexList.append()=CedarBackup2.util.RegexList-class.html#append,Method CedarBackup2.util.RegexMatchList.append()=CedarBackup2.util.RegexMatchList-class.html#append,Method CedarBackup2.util.RestrictedContentList.append()=CedarBackup2.util.RestrictedContentList-class.html#append"><a title="CedarBackup2.util.AbsolutePathList.append
669
672
CedarBackup2.util.ObjectTypeList.append
670
673
CedarBackup2.util.RegexList.append
671
674
CedarBackup2.util.RegexMatchList.append
672
675
CedarBackup2.util.RestrictedContentList.append" class="py-name" href="#" onclick="return doclink('link-35', 'append', 'link-35');">append</a></tt><tt class="py-op">(</tt><tt class="py-name">line</tt><tt class="py-op">.</tt><tt class="py-name">rstrip</tt><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">)</tt> </tt>
673
<a name="L492"></a><tt class="py-lineno">492</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-name">locales</tt> </tt>
674
</div><a name="L493"></a><tt class="py-lineno">493</tt> <tt class="py-line"> </tt>
675
<a name="L494"></a><tt class="py-lineno">494</tt> <tt class="py-line"> </tt>
676
<a name="L495"></a><tt class="py-lineno">495</tt> <tt class="py-line"><tt class="py-comment">####################################</tt> </tt>
677
<a name="L496"></a><tt class="py-lineno">496</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># hexFloatLiteralAllowed() function</tt> </tt>
678
<a name="L497"></a><tt class="py-lineno">497</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">####################################</tt> </tt>
679
<a name="L498"></a><tt class="py-lineno">498</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
680
<a name="hexFloatLiteralAllowed"></a><div id="hexFloatLiteralAllowed-def"><a name="L499"></a><tt class="py-lineno">499</tt> <a class="py-toggle" href="#" id="hexFloatLiteralAllowed-toggle" onclick="return toggle('hexFloatLiteralAllowed');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#hexFloatLiteralAllowed">hexFloatLiteralAllowed</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
681
</div><div id="hexFloatLiteralAllowed-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="hexFloatLiteralAllowed-expanded"><a name="L500"></a><tt class="py-lineno">500</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
682
<a name="L501"></a><tt class="py-lineno">501</tt> <tt class="py-line"><tt class="py-docstring"> Indicates whether hex float literals are allowed by the interpreter.</tt> </tt>
683
<a name="L502"></a><tt class="py-lineno">502</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
684
<a name="L503"></a><tt class="py-lineno">503</tt> <tt class="py-line"><tt class="py-docstring"> As far back as 2004, some Python documentation indicated that octal and hex</tt> </tt>
685
<a name="L504"></a><tt class="py-lineno">504</tt> <tt class="py-line"><tt class="py-docstring"> notation applies only to integer literals. However, prior to Python 2.5, it</tt> </tt>
686
<a name="L505"></a><tt class="py-lineno">505</tt> <tt class="py-line"><tt class="py-docstring"> was legal to construct a float with an argument like 0xAC. This check</tt> </tt>
687
<a name="L506"></a><tt class="py-lineno">506</tt> <tt class="py-line"><tt class="py-docstring"> provides a version-based indication of whether the current interpreter</tt> </tt>
688
<a name="L507"></a><tt class="py-lineno">507</tt> <tt class="py-line"><tt class="py-docstring"> supports that behavior.</tt> </tt>
689
<a name="L508"></a><tt class="py-lineno">508</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
690
<a name="L509"></a><tt class="py-lineno">509</tt> <tt class="py-line"><tt class="py-docstring"> This check exists so that unit tests can continue to test the same thing as</tt> </tt>
691
<a name="L510"></a><tt class="py-lineno">510</tt> <tt class="py-line"><tt class="py-docstring"> always for pre-2.5 interpreters (i.e. making sure backwards compatibility</tt> </tt>
692
<a name="L511"></a><tt class="py-lineno">511</tt> <tt class="py-line"><tt class="py-docstring"> doesn't break) while still continuing to work for later interpreters.</tt> </tt>
693
<a name="L512"></a><tt class="py-lineno">512</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
694
<a name="L513"></a><tt class="py-lineno">513</tt> <tt class="py-line"><tt class="py-docstring"> The returned value is True for Python <= 2.5, and False otherwise.</tt> </tt>
695
<a name="L514"></a><tt class="py-lineno">514</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
696
<a name="L515"></a><tt class="py-lineno">515</tt> <tt class="py-line"> <tt class="py-keyword">if</tt> <tt class="py-name">map</tt><tt class="py-op">(</tt><tt class="py-name">int</tt><tt class="py-op">,</tt> <tt class="py-op">[</tt><tt class="py-name">sys</tt><tt class="py-op">.</tt><tt class="py-name">version_info</tt><tt class="py-op">[</tt><tt class="py-number">0</tt><tt class="py-op">]</tt><tt class="py-op">,</tt> <tt class="py-name">sys</tt><tt class="py-op">.</tt><tt class="py-name">version_info</tt><tt class="py-op">[</tt><tt class="py-number">1</tt><tt class="py-op">]</tt><tt class="py-op">]</tt><tt class="py-op">)</tt> <tt class="py-op"><</tt> <tt class="py-op">[</tt><tt class="py-number">2</tt><tt class="py-op">,</tt> <tt class="py-number">5</tt><tt class="py-op">]</tt><tt class="py-op">:</tt> </tt>
697
<a name="L516"></a><tt class="py-lineno">516</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-name">True</tt> </tt>
698
<a name="L517"></a><tt class="py-lineno">517</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-name">False</tt> </tt>
699
</div><a name="L518"></a><tt class="py-lineno">518</tt> <tt class="py-line"> </tt><script type="text/javascript">
676
<a name="L495"></a><tt class="py-lineno">495</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-name">locales</tt> </tt>
677
</div><a name="L496"></a><tt class="py-lineno">496</tt> <tt class="py-line"> </tt>
678
<a name="L497"></a><tt class="py-lineno">497</tt> <tt class="py-line"> </tt>
679
<a name="L498"></a><tt class="py-lineno">498</tt> <tt class="py-line"><tt class="py-comment">####################################</tt> </tt>
680
<a name="L499"></a><tt class="py-lineno">499</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment"># hexFloatLiteralAllowed() function</tt> </tt>
681
<a name="L500"></a><tt class="py-lineno">500</tt> <tt class="py-line"><tt class="py-comment"></tt><tt class="py-comment">####################################</tt> </tt>
682
<a name="L501"></a><tt class="py-lineno">501</tt> <tt class="py-line"><tt class="py-comment"></tt> </tt>
683
<a name="hexFloatLiteralAllowed"></a><div id="hexFloatLiteralAllowed-def"><a name="L502"></a><tt class="py-lineno">502</tt> <a class="py-toggle" href="#" id="hexFloatLiteralAllowed-toggle" onclick="return toggle('hexFloatLiteralAllowed');">-</a><tt class="py-line"><tt class="py-keyword">def</tt> <a class="py-def-name" href="CedarBackup2.testutil-module.html#hexFloatLiteralAllowed">hexFloatLiteralAllowed</a><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
684
</div><div id="hexFloatLiteralAllowed-collapsed" style="display:none;" pad="+++" indent="++++"></div><div id="hexFloatLiteralAllowed-expanded"><a name="L503"></a><tt class="py-lineno">503</tt> <tt class="py-line"> <tt class="py-docstring">"""</tt> </tt>
685
<a name="L504"></a><tt class="py-lineno">504</tt> <tt class="py-line"><tt class="py-docstring"> Indicates whether hex float literals are allowed by the interpreter.</tt> </tt>
686
<a name="L505"></a><tt class="py-lineno">505</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
687
<a name="L506"></a><tt class="py-lineno">506</tt> <tt class="py-line"><tt class="py-docstring"> As far back as 2004, some Python documentation indicated that octal and hex</tt> </tt>
688
<a name="L507"></a><tt class="py-lineno">507</tt> <tt class="py-line"><tt class="py-docstring"> notation applied only to integer literals. However, prior to Python 2.5, it</tt> </tt>
689
<a name="L508"></a><tt class="py-lineno">508</tt> <tt class="py-line"><tt class="py-docstring"> was legal to construct a float with an argument like 0xAC on some platforms.</tt> </tt>
690
<a name="L509"></a><tt class="py-lineno">509</tt> <tt class="py-line"><tt class="py-docstring"> This check provides a an indication of whether the current interpreter</tt> </tt>
691
<a name="L510"></a><tt class="py-lineno">510</tt> <tt class="py-line"><tt class="py-docstring"> supports that behavior.</tt> </tt>
692
<a name="L511"></a><tt class="py-lineno">511</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
693
<a name="L512"></a><tt class="py-lineno">512</tt> <tt class="py-line"><tt class="py-docstring"> This check exists so that unit tests can continue to test the same thing as</tt> </tt>
694
<a name="L513"></a><tt class="py-lineno">513</tt> <tt class="py-line"><tt class="py-docstring"> always for pre-2.5 interpreters (i.e. making sure backwards compatibility</tt> </tt>
695
<a name="L514"></a><tt class="py-lineno">514</tt> <tt class="py-line"><tt class="py-docstring"> doesn't break) while still continuing to work for later interpreters.</tt> </tt>
696
<a name="L515"></a><tt class="py-lineno">515</tt> <tt class="py-line"><tt class="py-docstring"></tt> </tt>
697
<a name="L516"></a><tt class="py-lineno">516</tt> <tt class="py-line"><tt class="py-docstring"> The returned value is True if hex float literals are allowed, False otherwise.</tt> </tt>
698
<a name="L517"></a><tt class="py-lineno">517</tt> <tt class="py-line"><tt class="py-docstring"> """</tt> </tt>
699
<a name="L518"></a><tt class="py-lineno">518</tt> <tt class="py-line"> <tt class="py-keyword">if</tt> <tt class="py-name">map</tt><tt class="py-op">(</tt><tt class="py-name">int</tt><tt class="py-op">,</tt> <tt class="py-op">[</tt><tt class="py-name">sys</tt><tt class="py-op">.</tt><tt class="py-name">version_info</tt><tt class="py-op">[</tt><tt class="py-number">0</tt><tt class="py-op">]</tt><tt class="py-op">,</tt> <tt class="py-name">sys</tt><tt class="py-op">.</tt><tt class="py-name">version_info</tt><tt class="py-op">[</tt><tt class="py-number">1</tt><tt class="py-op">]</tt><tt class="py-op">]</tt><tt class="py-op">)</tt> <tt class="py-op"><</tt> <tt class="py-op">[</tt><tt class="py-number">2</tt><tt class="py-op">,</tt> <tt class="py-number">5</tt><tt class="py-op">]</tt> <tt class="py-keyword">and</tt> <tt class="py-keyword">not</tt> <tt id="link-36" class="py-name"><a title="CedarBackup2.testutil.platformWindows" class="py-name" href="#" onclick="return doclink('link-36', 'platformWindows', 'link-27');">platformWindows</a></tt><tt class="py-op">(</tt><tt class="py-op">)</tt><tt class="py-op">:</tt> </tt>
700
<a name="L519"></a><tt class="py-lineno">519</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-name">True</tt> </tt>
701
<a name="L520"></a><tt class="py-lineno">520</tt> <tt class="py-line"> <tt class="py-keyword">return</tt> <tt class="py-name">False</tt> </tt>
702
</div><a name="L521"></a><tt class="py-lineno">521</tt> <tt class="py-line"> </tt><script type="text/javascript">
701
704
expandto(location.href);