Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test command #206

Merged
merged 4 commits into from May 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

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

## 3.0.0-beta2 - 2019-03-22
- Disable Sentry's ErrorHandler, and report all errors using Symfony's events (#204)
Expand Down
55 changes: 55 additions & 0 deletions src/Command/SentryTestCommand.php
@@ -0,0 +1,55 @@
<?php

namespace Sentry\SentryBundle\Command;

use Sentry\State\Hub;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class SentryTestCommand extends Command
{
public function __construct()
{
parent::__construct('sentry:test');
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$currentHub = Hub::getCurrent();
$client = $currentHub->getClient();

if (! $client) {
$output->writeln('<error>No client found</error>');
$output->writeln('<info>Your DSN is probably missing, check your configuration</info>');

return 1;
}

$dsn = $client->getOptions()->getDsn();

if ($dsn) {
$output->writeln('<info>DSN correctly configured in the current client</info>');
} else {
$output->writeln('<error>No DSN configured in the current client, please check your configuration</error>');
$output->writeln('<info>To debug further, try bin/console debug:config sentry</info>');

return 1;
}

$output->writeln('Sending test message...');

$eventId = $currentHub->captureMessage('This is a test message from the Sentry bundle');

if ($eventId) {
$output->writeln("<info>Message sent successfully with ID $eventId</info>");
} else {
$output->writeln('<error>Message not sent!</error>');
$output->writeln('<warning>Check your DSN or your before_send callback if used</warning>');

return 1;
}

return 0;
}
}
4 changes: 4 additions & 0 deletions src/Resources/config/services.xml
Expand Up @@ -49,5 +49,9 @@
<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="%sentry.listener_priorities.sub_request%" />
<tag name="kernel.event_listener" event="kernel.finish_request" method="onKernelFinishRequest" priority="%sentry.listener_priorities.sub_request%" />
</service>

<service id="Sentry\SentryBundle\Command\SentryTestCommand" class="Sentry\SentryBundle\Command\SentryTestCommand" public="false">
<tag name="console.command" />
</service>
</services>
</container>
118 changes: 118 additions & 0 deletions test/Command/SentryTestCommandTest.php
@@ -0,0 +1,118 @@
<?php

namespace Sentry\SentryBundle\Test\Command;

use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Sentry\ClientInterface;
use Sentry\Options;
use Sentry\SentryBundle\Command\SentryTestCommand;
use Sentry\State\Hub;
use Sentry\State\HubInterface;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;

class SentryTestCommandTest extends TestCase
{
public function testExecuteSuccessfully(): void
{
$options = new Options(['dsn' => 'http://public:secret@example.com/sentry/1']);
$client = $this->prophesize(ClientInterface::class);
$client->getOptions()
->willReturn($options);

$hub = $this->prophesize(HubInterface::class);
$hub->getClient()
->willReturn($client->reveal());
$lastEventId = 'abcdef0123456';
$hub->captureMessage(Argument::containingString('test'), Argument::cetera())
->shouldBeCalled()
->willReturn($lastEventId);

Hub::setCurrent($hub->reveal());

$commandTester = $this->executeCommand();

$output = $commandTester->getDisplay();
$this->assertContains('DSN correctly configured', $output);
$this->assertContains('Sending test message', $output);
$this->assertContains('Message sent', $output);
$this->assertContains($lastEventId, $output);
$this->assertSame(0, $commandTester->getStatusCode());
}

public function testExecuteFailsDueToMissingDSN(): void
{
$client = $this->prophesize(ClientInterface::class);
$client->getOptions()
->willReturn(new Options());

$hub = $this->prophesize(HubInterface::class);
$hub->getClient()
->willReturn($client->reveal());

Hub::setCurrent($hub->reveal());

$commandTester = $this->executeCommand();

$this->assertNotSame(0, $commandTester->getStatusCode());
$output = $commandTester->getDisplay();
$this->assertContains('No DSN configured', $output);
$this->assertContains('try bin/console debug:config sentry', $output);
}

public function testExecuteFailsDueToMessageNotSent(): void
{
$options = new Options(['dsn' => 'http://public:secret@example.com/sentry/1']);
$client = $this->prophesize(ClientInterface::class);
$client->getOptions()
->willReturn($options);

$hub = $this->prophesize(HubInterface::class);
$hub->getClient()
->willReturn($client->reveal());
$hub->captureMessage(Argument::containingString('test'), Argument::cetera())
->shouldBeCalled()
->willReturn(null);

Hub::setCurrent($hub->reveal());

$commandTester = $this->executeCommand();

$this->assertNotSame(0, $commandTester->getStatusCode());
$output = $commandTester->getDisplay();
$this->assertContains('DSN correctly configured', $output);
$this->assertContains('Sending test message', $output);
$this->assertContains('Message not sent', $output);
}

public function testExecuteFailsDueToMissingClient(): void
{
$hub = $this->prophesize(HubInterface::class);
$hub->getClient()
->willReturn(null);

Hub::setCurrent($hub->reveal());

$commandTester = $this->executeCommand();

$this->assertNotSame(0, $commandTester->getStatusCode());
$output = $commandTester->getDisplay();
$this->assertContains('No client found', $output);
$this->assertContains('DSN is probably missing', $output);
}

private function executeCommand(): CommandTester
{
$application = new Application();
$application->add(new SentryTestCommand());

$command = $application->find('sentry:test');
$commandTester = new CommandTester($command);
$commandTester->execute([
'command' => $command->getName(),
]);

return $commandTester;
}
}
10 changes: 10 additions & 0 deletions test/SentryBundleTest.php
Expand Up @@ -7,6 +7,7 @@
use Sentry\Integration\ExceptionListenerIntegration;
use Sentry\Integration\IntegrationInterface;
use Sentry\Integration\RequestIntegration;
use Sentry\SentryBundle\Command\SentryTestCommand;
use Sentry\SentryBundle\DependencyInjection\SentryExtension;
use Sentry\SentryBundle\EventListener\ConsoleListener;
use Sentry\SentryBundle\EventListener\ErrorListener;
Expand Down Expand Up @@ -121,6 +122,15 @@ public function testContainerHasErrorListenerConfiguredCorrectly(): void
$this->assertSame($expectedTag, $consoleListener->getTags());
}

public function testContainerHasTestCommandRegisteredCorrectly(): void
{
$container = $this->getContainer();

$consoleListener = $container->getDefinition(SentryTestCommand::class);

$this->assertArrayHasKey('console.command', $consoleListener->getTags());
}

public function testIntegrationsListenersAreDisabledByDefault(): void
{
$container = $this->getContainer();
Expand Down