Skip to content

Commit

Permalink
Merge pull request #34 from msiebeneicher/feature/add_validation_command
Browse files Browse the repository at this point in the history
Feature/add validation command
  • Loading branch information
msiebeneicher committed Sep 21, 2015
2 parents 0fc056f + 19e747d commit 68cab54
Show file tree
Hide file tree
Showing 5 changed files with 316 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# dev-master (v0.4.x)
2015-09-20 msiebeneicher <marc.siebeneicher@trivago.com>
* [issue#17] - Added optional parameters to configure command
* [issue#13] - Added validation command
* Improved AbstractCommand by adding CommandUtils

# v0.3.0
2015-09-15 msiebeneicher <marc.siebeneicher@trivago.com>
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ Display upcoming jobs in a specified timeframe
```Shell
bin/chapi scheduling [options]
```

Options:
-s, --starttime[=STARTTIME] Start time to display the jobs
-e, --endtime[=ENDTIME] End time to display the jobs
Expand All @@ -113,11 +114,21 @@ Configure application and add necessary configs
```Shell
bin/chapi configure
```

Options:
-u, --chronos_url[=CHRONOS_URL] The chronos url (inclusive port)
-d, --cache_dir[=CACHE_DIR] Path to cache directory
-r, --repository_dir[=REPOSITORY_DIR] Root path to your job files
### validate
Validate local jobs

```Shell
bin/chapi validate [<jobmames>]...
```

Arguments:
jobmames Jobs to validate

## Supported Chronos versions
* v2.3
Expand Down
1 change: 1 addition & 0 deletions src/ChapiApplication.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ private function getCommands()
new Commands\ResetCommand(),
new Commands\SchedulingViewCommand(),
new Commands\StatusCommand(),
new Commands\ValidationCommand(),
];
}
}
139 changes: 139 additions & 0 deletions src/Commands/ValidationCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<?php
/**
* @package: chapi
*
* @author: msiebeneicher
* @since: 2015-09-20
*
* @link: http://
*/

namespace Chapi\Commands;

use Chapi\Commands\AbstractCommand;
use Chapi\Component\Command\JobUtils;
use Chapi\Entity\Chronos\JobEntity;
use Chapi\Service\JobRepository\JobEntityValidatorServiceInterface;
use Chapi\Service\JobRepository\JobRepositoryInterface;

class ValidationCommand extends AbstractCommand
{

/**
* @var array[]
*/
private $aInvalidJobs = [];

/**
* Configures the current command.
*/
protected function configure()
{
$this->setName('validate')
->setDescription('Validate local jobs')
;

JobUtils::configureJobNamesArgument($this, 'Jobs to validate');
}

/**
* @inheritDoc
*/
protected function process()
{
$_aJobNames = JobUtils::getJobNames($this->oInput, $this);
$_aJobsToValidate = (JobUtils::isWildcard($_aJobNames))
? $this->getLocalJobs()
: $_aJobNames
;

if ($this->hasInvalidJobs($_aJobsToValidate))
{
$this->oOutput->writeln("<comment>Founded invalid jobs:</comment>\n");

foreach ($this->getInvalidJobsByJobNames($_aJobsToValidate) as $_sJobName => $_aInvalidProperties)
{
$this->printInvalidJobProperties($_sJobName, $_aInvalidProperties);
}

return 1;
}

//else
$this->oOutput->writeln('<info>All checked jobs looks valid</info>');
return 0;
}

/**
* @param string[] $aJobs
* @return bool
*/
private function hasInvalidJobs(array $aJobs)
{
$_aInvalidJobs = $this->getInvalidJobsByJobNames($aJobs);
return (count($_aInvalidJobs) > 0);
}

/**
* @param array $aJobs
* @return array
*/
private function getInvalidJobsByJobNames(array $aJobs)
{
$_sKey = md5(implode('.', $aJobs));

if (isset($this->aInvalidJobs[$_sKey]))
{
return $this->aInvalidJobs[$_sKey];
}

$_aInvalidJobs = [];

/** @var JobEntityValidatorServiceInterface $_oJobEntityValidationService */
$_oJobEntityValidationService = $this->getContainer()->get(JobEntityValidatorServiceInterface::DIC_NAME);

/** @var JobRepositoryInterface $_oJobRepositoryLocale */
$_oJobRepositoryLocale = $this->getContainer()->get(JobRepositoryInterface::DIC_NAME_FILESYSTEM);

foreach ($aJobs as $_sJobName)
{
$_oJobEntity = $_oJobRepositoryLocale->getJob($_sJobName);

if (false === $_oJobEntityValidationService->isEntityValid($_oJobEntity))
{
$_aInvalidJobs[$_sJobName] = $_oJobEntityValidationService->getInvalidProperties($_oJobEntity);
}
}

return $this->aInvalidJobs[$_sKey] = $_aInvalidJobs;
}

/**
* @param string $sJobName
* @param string[] $aInvalidProperties
*/
private function printInvalidJobProperties($sJobName, array $aInvalidProperties)
{
$_sFormat = "\t<fg=red>%s:\t%s</>";
$this->oOutput->writeln(sprintf($_sFormat, $sJobName, implode(', ', $aInvalidProperties)));
}

/**
* @return string[]
*/
private function getLocalJobs()
{
$_aJobNames = [];

/** @var JobRepositoryInterface $_oJobRepositoryLocale */
$_oJobRepositoryLocale = $this->getContainer()->get(JobRepositoryInterface::DIC_NAME_FILESYSTEM);

/** @var JobEntity $_oJobEntity */
foreach ($_oJobRepositoryLocale->getJobs() as $_oJobEntity)
{
$_aJobNames[] = $_oJobEntity->name;
}

return $_aJobNames;
}
}
163 changes: 163 additions & 0 deletions test/unit/Command/ValidationCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<?php
/**
* @package: chapi
*
* @author: msiebeneicher
* @since: 2015-09-20
*
* @link: http://
*/

namespace unit\Command;

use Chapi\Commands\ValidationCommand;
use Chapi\Component\Command\JobUtilsInterface;
use Chapi\Entity\Chronos\JobEntity;
use Chapi\Service\JobRepository\JobEntityValidatorServiceInterface;
use Chapi\Service\JobRepository\JobRepositoryInterface;
use ChapiTest\src\TestTraits\CommandTestTrait;
use ChapiTest\src\TestTraits\JobEntityTrait;
use Prophecy\Argument;

class ValidationCommandTest extends \PHPUnit_Framework_TestCase
{
use CommandTestTrait;
use JobEntityTrait;

/** @var \Prophecy\Prophecy\ObjectProphecy */
private $oJobEntityValidatorService;

/** @var \Prophecy\Prophecy\ObjectProphecy */
private $oJobRepositoryLocale;

public function setUp()
{
$this->setUpCommandDependencies();

$this->oJobEntityValidatorService = $this->prophesize('Chapi\Service\JobRepository\JobEntityValidatorServiceInterface');

$this->oJobRepositoryLocale = $this->prophesize('Chapi\Service\JobRepository\JobRepositoryInterface');
}

public function testValidationWithWildcardSuccess()
{
$this->oInput->getArgument(Argument::exact(JobUtilsInterface::ARGUMENT_JOBNAMES))->willReturn(['*'])->shouldBeCalledTimes(1);

$_oJobCollection = $this->createJobCollection();
$this->oJobRepositoryLocale->getJobs()->shouldBeCalledTimes(1)->willReturn($_oJobCollection);
$this->oJobRepositoryLocale->getJob(Argument::exact('JobA'))->shouldBeCalledTimes(1)->willReturn($_oJobCollection->offsetGet('JobA'));
$this->oJobRepositoryLocale->getJob(Argument::exact('JobB'))->shouldBeCalledTimes(1)->willReturn($_oJobCollection->offsetGet('JobB'));
$this->oJobRepositoryLocale->getJob(Argument::exact('JobC'))->shouldBeCalledTimes(1)->willReturn($_oJobCollection->offsetGet('JobC'));

$this->oJobEntityValidatorService->isEntityValid(Argument::type('Chapi\Entity\Chronos\JobEntity'))->shouldBeCalledTimes(3)->willReturn(true);

$this->oContainer
->get(Argument::exact(JobRepositoryInterface::DIC_NAME_FILESYSTEM))
->shouldBeCalled()
->willReturn($this->oJobRepositoryLocale->reveal())
;

$this->oContainer
->get(Argument::exact(JobEntityValidatorServiceInterface::DIC_NAME))
->shouldBeCalled()
->willReturn($this->oJobEntityValidatorService->reveal())
;

$_oCommand = new ValidationCommandDummy();
$_oCommand::$oContainerDummy = $this->oContainer->reveal();

$this->assertEquals(
0,
$_oCommand->run(
$this->oInput->reveal(),
$this->oOutput->reveal()
)
);
}

public function testValidationWithWildcardFailure()
{
$this->oInput->getArgument(Argument::exact(JobUtilsInterface::ARGUMENT_JOBNAMES))->willReturn(['*'])->shouldBeCalledTimes(1);

$_oJobCollection = $this->createJobCollection();

$this->oJobRepositoryLocale->getJobs()->shouldBeCalledTimes(1)->willReturn($_oJobCollection);
$this->oJobRepositoryLocale->getJob(Argument::exact('JobA'))->shouldBeCalledTimes(1)->willReturn($_oJobCollection->offsetGet('JobA'));
$this->oJobRepositoryLocale->getJob(Argument::exact('JobB'))->shouldBeCalledTimes(1)->willReturn($_oJobCollection->offsetGet('JobB'));
$this->oJobRepositoryLocale->getJob(Argument::exact('JobC'))->shouldBeCalledTimes(1)->willReturn($_oJobCollection->offsetGet('JobC'));

$this->oJobEntityValidatorService->isEntityValid(Argument::type('Chapi\Entity\Chronos\JobEntity'))->shouldBeCalledTimes(3)->willReturn(false);
$this->oJobEntityValidatorService->getInvalidProperties(Argument::type('Chapi\Entity\Chronos\JobEntity'))->shouldBeCalledTimes(3)->willReturn(['epsilon', 'command']);

$this->oContainer
->get(Argument::exact(JobRepositoryInterface::DIC_NAME_FILESYSTEM))
->shouldBeCalled()
->willReturn($this->oJobRepositoryLocale->reveal())
;

$this->oContainer
->get(Argument::exact(JobEntityValidatorServiceInterface::DIC_NAME))
->shouldBeCalled()
->willReturn($this->oJobEntityValidatorService->reveal())
;

$_oCommand = new ValidationCommandDummy();
$_oCommand::$oContainerDummy = $this->oContainer->reveal();

$this->assertEquals(
1,
$_oCommand->run(
$this->oInput->reveal(),
$this->oOutput->reveal()
)
);
}

public function testValidationWithoutWildcardSuccess()
{
$this->oInput->getArgument(Argument::exact(JobUtilsInterface::ARGUMENT_JOBNAMES))->willReturn(['JobA'])->shouldBeCalledTimes(1);

$_oJobEntity = $this->getValidScheduledJobEntity();
$this->oJobRepositoryLocale->getJob(Argument::exact('JobA'))->shouldBeCalledTimes(1)->willReturn($_oJobEntity);

$this->oJobEntityValidatorService->isEntityValid(Argument::exact($_oJobEntity))->shouldBeCalledTimes(1)->willReturn(true);

$this->oContainer
->get(Argument::exact(JobRepositoryInterface::DIC_NAME_FILESYSTEM))
->shouldBeCalled()
->willReturn($this->oJobRepositoryLocale->reveal())
;

$this->oContainer
->get(Argument::exact(JobEntityValidatorServiceInterface::DIC_NAME))
->shouldBeCalled()
->willReturn($this->oJobEntityValidatorService->reveal())
;

$_oCommand = new ValidationCommandDummy();
$_oCommand::$oContainerDummy = $this->oContainer->reveal();

$this->assertEquals(
0,
$_oCommand->run(
$this->oInput->reveal(),
$this->oOutput->reveal()
)
);
}
}

class ValidationCommandDummy extends ValidationCommand
{
public static $oContainerDummy;

protected function getContainer()
{
return self::$oContainerDummy;
}

protected function isAppRunable()
{
return true;
}
}

0 comments on commit 68cab54

Please sign in to comment.