Changeset View
Changeset View
Standalone View
Standalone View
src/error/__tests__/PhutilOpaqueEnvelopeTestCase.php
<?php | <?php | ||||
final class PhutilOpaqueEnvelopeTestCase extends PhutilTestCase { | final class PhutilOpaqueEnvelopeTestCase extends PhutilTestCase { | ||||
public function testOpaqueEnvelope() { | public function testOpaqueEnvelope() { | ||||
// NOTE: When run via "arc diff", this test's trace may include portions of | // NOTE: When run via "arc diff", this test's trace may include portions of | ||||
// the diff itself, and thus this source code. Since we look for the secret | // the diff itself, and thus this source code. Since we look for the secret | ||||
// in traces later on, split it apart here so that invocation via | // in traces later on, split it apart here so that invocation via | ||||
// "arc diff" doesn't create a false test failure. | // "arc diff" doesn't create a false test failure. | ||||
$secret = 'hunter'.'2'; | $secret = 'hunter'.'2'; | ||||
// Also split apart this "signpost" value which we are not going to put in | |||||
// an envelope. We expect to be able to find it in the argument lists in | |||||
// stack traces, and don't want a false positive. | |||||
$signpost = 'shaman'.'3'; | |||||
$envelope = new PhutilOpaqueEnvelope($secret); | $envelope = new PhutilOpaqueEnvelope($secret); | ||||
$this->assertFalse(strpos(var_export($envelope, true), $secret)); | $this->assertFalse(strpos(var_export($envelope, true), $secret)); | ||||
$this->assertFalse(strpos(print_r($envelope, true), $secret)); | $this->assertFalse(strpos(print_r($envelope, true), $secret)); | ||||
ob_start(); | ob_start(); | ||||
var_dump($envelope); | var_dump($envelope); | ||||
$dump = ob_get_clean(); | $dump = ob_get_clean(); | ||||
$this->assertFalse(strpos($dump, $secret)); | $this->assertFalse(strpos($dump, $secret)); | ||||
try { | try { | ||||
$this->throwTrace($envelope); | $this->throwTrace($envelope, $signpost); | ||||
} catch (Exception $ex) { | } catch (Exception $ex) { | ||||
$trace = $ex->getTrace(); | $trace = $ex->getTrace(); | ||||
$this->assertFalse(strpos(print_r($trace, true), $secret)); | |||||
// NOTE: The entire trace may be very large and contain complex | |||||
// recursive datastructures. Look at only the last few frames: we expect | |||||
// to see the signpost value but not the secret. | |||||
$trace = array_slice($trace, 0, 2); | |||||
$trace = print_r($trace, true); | |||||
$this->assertTrue(strpos($trace, $signpost) !== false); | |||||
epriestley: (This is debugging stuff which I cleaned up locally after actually getting tests to run.) | |||||
Not Done Inline ActionsWhy not just $this->assertTrue(strpos($trace, $signpost)? amckinley: Why not just `$this->assertTrue(strpos($trace, $signpost)`? | |||||
$this->assertFalse(strpos($trace, $secret)); | |||||
} | } | ||||
$backtrace = $this->getBacktrace($envelope); | $backtrace = $this->getBacktrace($envelope, $signpost); | ||||
$backtrace = array_slice($backtrace, 0, 2); | |||||
$this->assertTrue(strpos($trace, $signpost) !== false); | |||||
$this->assertFalse(strpos(print_r($backtrace, true), $secret)); | $this->assertFalse(strpos(print_r($backtrace, true), $secret)); | ||||
$this->assertEqual($secret, $envelope->openEnvelope()); | $this->assertEqual($secret, $envelope->openEnvelope()); | ||||
} | } | ||||
private function throwTrace($v) { | private function throwTrace($v, $w) { | ||||
throw new Exception('!'); | throw new Exception('!'); | ||||
} | } | ||||
private function getBacktrace($v) { | private function getBacktrace($v, $w) { | ||||
return debug_backtrace(); | return debug_backtrace(); | ||||
} | } | ||||
} | } |
(This is debugging stuff which I cleaned up locally after actually getting tests to run.)