Skip to content

Commit 12f00db

Browse files
authored
Merge pull request #206 from getsentry/add-test-command
Add test command
2 parents 2845df5 + 808f4c2 commit 12f00db

File tree

5 files changed

+188
-0
lines changed

5 files changed

+188
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
- Add the `sentry:test` command, to test if the Sentry SDK is functioning properly.
89

910
## 3.0.0-beta2 - 2019-03-22
1011
- Disable Sentry's ErrorHandler, and report all errors using Symfony's events (#204)

src/Command/SentryTestCommand.php

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace Sentry\SentryBundle\Command;
4+
5+
use Sentry\State\Hub;
6+
use Symfony\Component\Console\Command\Command;
7+
use Symfony\Component\Console\Input\InputInterface;
8+
use Symfony\Component\Console\Output\OutputInterface;
9+
10+
class SentryTestCommand extends Command
11+
{
12+
public function __construct()
13+
{
14+
parent::__construct('sentry:test');
15+
}
16+
17+
protected function execute(InputInterface $input, OutputInterface $output): int
18+
{
19+
$currentHub = Hub::getCurrent();
20+
$client = $currentHub->getClient();
21+
22+
if (! $client) {
23+
$output->writeln('<error>No client found</error>');
24+
$output->writeln('<info>Your DSN is probably missing, check your configuration</info>');
25+
26+
return 1;
27+
}
28+
29+
$dsn = $client->getOptions()->getDsn();
30+
31+
if ($dsn) {
32+
$output->writeln('<info>DSN correctly configured in the current client</info>');
33+
} else {
34+
$output->writeln('<error>No DSN configured in the current client, please check your configuration</error>');
35+
$output->writeln('<info>To debug further, try bin/console debug:config sentry</info>');
36+
37+
return 1;
38+
}
39+
40+
$output->writeln('Sending test message...');
41+
42+
$eventId = $currentHub->captureMessage('This is a test message from the Sentry bundle');
43+
44+
if ($eventId) {
45+
$output->writeln("<info>Message sent successfully with ID $eventId</info>");
46+
} else {
47+
$output->writeln('<error>Message not sent!</error>');
48+
$output->writeln('<warning>Check your DSN or your before_send callback if used</warning>');
49+
50+
return 1;
51+
}
52+
53+
return 0;
54+
}
55+
}

src/Resources/config/services.xml

+4
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,9 @@
4949
<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="%sentry.listener_priorities.sub_request%" />
5050
<tag name="kernel.event_listener" event="kernel.finish_request" method="onKernelFinishRequest" priority="%sentry.listener_priorities.sub_request%" />
5151
</service>
52+
53+
<service id="Sentry\SentryBundle\Command\SentryTestCommand" class="Sentry\SentryBundle\Command\SentryTestCommand" public="false">
54+
<tag name="console.command" />
55+
</service>
5256
</services>
5357
</container>
+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php
2+
3+
namespace Sentry\SentryBundle\Test\Command;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use Prophecy\Argument;
7+
use Sentry\ClientInterface;
8+
use Sentry\Options;
9+
use Sentry\SentryBundle\Command\SentryTestCommand;
10+
use Sentry\State\Hub;
11+
use Sentry\State\HubInterface;
12+
use Symfony\Component\Console\Application;
13+
use Symfony\Component\Console\Tester\CommandTester;
14+
15+
class SentryTestCommandTest extends TestCase
16+
{
17+
public function testExecuteSuccessfully(): void
18+
{
19+
$options = new Options(['dsn' => 'http://public:[email protected]/sentry/1']);
20+
$client = $this->prophesize(ClientInterface::class);
21+
$client->getOptions()
22+
->willReturn($options);
23+
24+
$hub = $this->prophesize(HubInterface::class);
25+
$hub->getClient()
26+
->willReturn($client->reveal());
27+
$lastEventId = 'abcdef0123456';
28+
$hub->captureMessage(Argument::containingString('test'), Argument::cetera())
29+
->shouldBeCalled()
30+
->willReturn($lastEventId);
31+
32+
Hub::setCurrent($hub->reveal());
33+
34+
$commandTester = $this->executeCommand();
35+
36+
$output = $commandTester->getDisplay();
37+
$this->assertContains('DSN correctly configured', $output);
38+
$this->assertContains('Sending test message', $output);
39+
$this->assertContains('Message sent', $output);
40+
$this->assertContains($lastEventId, $output);
41+
$this->assertSame(0, $commandTester->getStatusCode());
42+
}
43+
44+
public function testExecuteFailsDueToMissingDSN(): void
45+
{
46+
$client = $this->prophesize(ClientInterface::class);
47+
$client->getOptions()
48+
->willReturn(new Options());
49+
50+
$hub = $this->prophesize(HubInterface::class);
51+
$hub->getClient()
52+
->willReturn($client->reveal());
53+
54+
Hub::setCurrent($hub->reveal());
55+
56+
$commandTester = $this->executeCommand();
57+
58+
$this->assertNotSame(0, $commandTester->getStatusCode());
59+
$output = $commandTester->getDisplay();
60+
$this->assertContains('No DSN configured', $output);
61+
$this->assertContains('try bin/console debug:config sentry', $output);
62+
}
63+
64+
public function testExecuteFailsDueToMessageNotSent(): void
65+
{
66+
$options = new Options(['dsn' => 'http://public:[email protected]/sentry/1']);
67+
$client = $this->prophesize(ClientInterface::class);
68+
$client->getOptions()
69+
->willReturn($options);
70+
71+
$hub = $this->prophesize(HubInterface::class);
72+
$hub->getClient()
73+
->willReturn($client->reveal());
74+
$hub->captureMessage(Argument::containingString('test'), Argument::cetera())
75+
->shouldBeCalled()
76+
->willReturn(null);
77+
78+
Hub::setCurrent($hub->reveal());
79+
80+
$commandTester = $this->executeCommand();
81+
82+
$this->assertNotSame(0, $commandTester->getStatusCode());
83+
$output = $commandTester->getDisplay();
84+
$this->assertContains('DSN correctly configured', $output);
85+
$this->assertContains('Sending test message', $output);
86+
$this->assertContains('Message not sent', $output);
87+
}
88+
89+
public function testExecuteFailsDueToMissingClient(): void
90+
{
91+
$hub = $this->prophesize(HubInterface::class);
92+
$hub->getClient()
93+
->willReturn(null);
94+
95+
Hub::setCurrent($hub->reveal());
96+
97+
$commandTester = $this->executeCommand();
98+
99+
$this->assertNotSame(0, $commandTester->getStatusCode());
100+
$output = $commandTester->getDisplay();
101+
$this->assertContains('No client found', $output);
102+
$this->assertContains('DSN is probably missing', $output);
103+
}
104+
105+
private function executeCommand(): CommandTester
106+
{
107+
$application = new Application();
108+
$application->add(new SentryTestCommand());
109+
110+
$command = $application->find('sentry:test');
111+
$commandTester = new CommandTester($command);
112+
$commandTester->execute([
113+
'command' => $command->getName(),
114+
]);
115+
116+
return $commandTester;
117+
}
118+
}

test/SentryBundleTest.php

+10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Sentry\Integration\ExceptionListenerIntegration;
88
use Sentry\Integration\IntegrationInterface;
99
use Sentry\Integration\RequestIntegration;
10+
use Sentry\SentryBundle\Command\SentryTestCommand;
1011
use Sentry\SentryBundle\DependencyInjection\SentryExtension;
1112
use Sentry\SentryBundle\EventListener\ConsoleListener;
1213
use Sentry\SentryBundle\EventListener\ErrorListener;
@@ -121,6 +122,15 @@ public function testContainerHasErrorListenerConfiguredCorrectly(): void
121122
$this->assertSame($expectedTag, $consoleListener->getTags());
122123
}
123124

125+
public function testContainerHasTestCommandRegisteredCorrectly(): void
126+
{
127+
$container = $this->getContainer();
128+
129+
$consoleListener = $container->getDefinition(SentryTestCommand::class);
130+
131+
$this->assertArrayHasKey('console.command', $consoleListener->getTags());
132+
}
133+
124134
public function testIntegrationsListenersAreDisabledByDefault(): void
125135
{
126136
$container = $this->getContainer();

0 commit comments

Comments
 (0)