Symfony Console Commands in scheduler in TYPO3 8 - typo3

I wrote a symfony controller command which works as expected in cli. But I would prefer to trigger the script via scheduler. Is there a possibility to get the symfony command in the tasks of scheduler? (TYPO3 8)

You have to create your own task for scheduler as described in documentation of EXT:scheduler https://docs.typo3.org/c/typo3/cms-scheduler/master/en-us/DevelopersGuide/CreatingTasks/Index.html
class MyTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask {
public function execute() {
$businessLogic = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\Vendor\Extension\BusinessLogic::class);
$businessLogic->run(arg1, arg2, …);
}
}

Related

How to contol all spring batch jobs running as scheduled cron jobs by passing a boolean flag to disable or enable the jobs?

I have created a job status table where i have a boolean flag based on that i am returning the cron expreesion(active cron or hypen(-) cron) and my scheduler will work. Boolean flag will be updated if you want to enable or disable all spring batch jobs.
How can we contol the flag in the application otherwise we will have issues in running the cron expression?
#Scheduled(cron = "#{#getCronValueDevice}")
#Scheduled(cron = "#{#getCronValueStorage}")
#Bean
public String getCronValueDevice() {
JobStatus jobStatus = jobStatusRepository.findByJobName(BatchJobConstants.DEVICE_JOB_NAME);
if (jobStatus != null && jobStatus.getIsActive()) {
return jobStatus.getActiveCronExpression();
} else {
return "-";
}
If the goal is to enable/disable scheduled jobs using a flag, I would keep it simple and make the job launching code conditioned by that flag, something like:
#Scheduled(cron = "#{your.cron.expression}")
public void runJob() {
boolean enabled = ... // dynamically load the flag as needed
if (enabled) {
// run the job
}
}
This does not require to change the cron expression on the fly to enable/disable the schedule. When the flag is false, the job will not be executed at subsequent schedules unless it is reactivated again.
BTW, kubernetes provides a similar feature to suspend/resume cron jobs (this can be done on the fly by patching the cron job specification).

NUnit3 Tests Don't seem to be running in parallel

I have the following
[assembly: LevelOfParallelism(10)]
[Parallelizable(ParallelScope.Self)]
public class MessageHandlerTests
{
[Test]
public async Task WhenCallingHandle_ShouldInvokeConsumer(
[Values(1, 25)] int messageCount,
[Values(5, 12)] int processingTimeSeconds,
[Values(SendMode.AzureServiceBus, SendMode.BrokeredMessageSender)] SendMode sendMode,
[Values(ConsumerAction.None, ConsumerAction.Publish, ConsumerAction.Reply, ConsumerAction.Send)] ConsumerAction consumerAction)
{
...
}
}
It's a semi long running test (about 30 seconds) and I have logging throughout the test and as far as I can tell it's not running in parallel, either via Test Explorer or via nunit3-console.exe
Any ideas on what I'm doing wrong?
Resolved this by setting
[Parallelizable(ParallelScope.All)]
Issue seems to be an unexpected behavior when using combinatorial tests. Note this is a newly added enum value.

How can I debug my command controller?

I have created a command controller and registered it on my scheduler, like:
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['extbase']['commandControllers'][] =
'Blog\\Events\\Command\\UpdateCommandController';
I can execute my command with the scheduler; but, if I enter a var_dump or die in my UpdateCommandController, I will not see any change in TYPO3 backend.
How can debug my command controller. And, what is the correct way to do this?
Can someone give me a tip?
Here is command controller, which i will to debug:
namespace Blog\Events\Command;
use TYPO3\CMS\Extbase\Mvc\Controller\CommandController;
class UpdateCommandController extends CommandController
{
/**
* Eventsrepository
*
* #var \Blog\Events\Domain\Repository\EventsRepository
* #inject
*/
protected $eventsRepository;
public function updateCommand()
{
echo "hello world";
}
}
You can debug the controller by calling it from the command line. To do this, you need a backend user _cli_lowlevel (with no privileges).
Then you can execute the script typo3/cli_dispatch.phpsh using php. To execute your command controller, you need to execute a command similar to this:
php typo3/cli_dispatch.phpsh extbase <controller-name>:<action-name>
Both <controller-name> and <action-name> would be update in your case. To see all available actions from CommandControllers, execute this command:
php typo3/cli_dispatch.phpsh extbase help
You can use Typo3 extension Developer Log for debuging.
Extension create log records in the database and show them in backend module.
Example of use in Extbase PHP code:
$arguments = 'any-data-for-log';
\TYPO3\CMS\Core\Utility\GeneralUtility::devlog(
'[ClassName::functionName]',
'extension_name',
1, // severity
array('arguments' => $arguments) // log data
);
This is a better way (for me).
In TYPO3 9 and above you can log like this:
$this->logger = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Log\LogManager::class)->getLogger(__CLASS__);
$logWriter = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Core\Log\Writer\FileWriter', ['logFile' => 'typo3temp/logs/my_import.log']);
$this->logger->addWriter(\TYPO3\CMS\Core\Log\LogLevel::INFO, $logWriter);
and then
$this->logger->error($e->getMessage());

gradle get value from extension (pass as input to task)

I have following code in my plugin:
#Override
void apply(Project project) {
project.extensions.create(EXTENSION,TestExtension)
project.task("task1") << {
println "Task 1"
println(project.mmm.test)
def extension = project.extensions.findByName(EXTENSION)
println(extension.test)
}
project.task("task2",type: TestTask) {
println "Task 2 "
def extension = project.extensions.findByName(EXTENSION)
// conventionMapping.test = {extension.test}
// println(project.extensions.findByName(EXTENSION).test)
// test = "test"
}
}
In task 1 extension.test return correct value. However in task2 extension.test always return null. What I am doing wrong? Is there a better way to pass some of the extensions values as input for task? I am using gradle 1.12 with jdk 1.8 on Mac. Best Regards
Edit :correct version:
project.task("task2", type: TestTask) {
project.afterEvaluate {
def extension = project.extensions.findByName(EXTENSION)
println(project.extensions.findByName(EXTENSION).test)
test = project.extensions.findByName(EXTENSION).test
}
}
task1 prints the value at execution time (notice the <<), task2 at configuration time (before the rest of the build script after the apply plugin: ... has been evaluated). This explains why the println for task1 works as expected, and the println for task2 doesn't.
However, configuring a task at execution time is too late. Instead, a plugin needs to defer reading user-provided values until the end of the configuration phase (after build scripts have been evaluated, but before any task has been executed). There are several techniques for doing so. One of the simpler ones is to wrap any such read access with project.afterEvaluate { ... }.
Updated answer as some time has passed and Gradle evolved its concepts and its syntax in the meantime.
To use up-to-date and optimally configured task you should use following syntax:
tasks.register("task1") {
doLast {
def extension = project.extensions.findByName(EXTENSION)
println(project.extensions.findByName(EXTENSION).test)
test = project.extensions.findByName(EXTENSION).test
}
}
Task Action:
A task has both configuration and actions. When using the doLast, you
are simply using a shortcut to define an action. Code defined in the
configuration section of your task will get executed during the
configuration phase of the build regardless of what task was targeted.
Deprecated << Operator
<< was deprecated in 4.x and removed in 5.0. See task action (doLast) on how to evaluate task logic at execution phase when all extensions and configurations should be evaluated.
Task Configuration Avoidance
To avoid the cost of creating a task if this won't be executed on your invoked Gradle command TaskContainer.register(String) method.
Avoid afterEvaluate
afterEvaluate should in most cases be avoided, see #sterling's comments from the link. You have now the possibility to evaluate task action part in execution phase, and additionally you can also rely on Task Inputs/Outputs with the combination of Lazy Configuration.

How to stop PHPUnit from adding included/required files as part of the testsuite?

I tried to follow the PHPUnit manual on how to setup a testsuite with a custom test execution order. I now realized that i only need these lines and some includes to get the suite working:
public static function suite()
{
$suite = new PHPUnit_Framework_TestSuite('Package');
return $suite;
}
But when i use the above lines the test execution order is defined by the sort order of my includes. And when i try to change it via suite() as followes the tests are executed twice, first in the sort order as defined by suite() and after that in the sort order of the includes:
public static function suite()
{
$suite = new PHPUnit_Framework_TestSuite('Package');
$suite->addTestSuite('Package_Class1Test');
$suite->addTestSuite('Package_Class2Test');
$suite->addTestSuite('Package_Class3Test');
return $suite;
}
Includes are done by:
require_once 'Package/Class3Test.php';
require_once 'Package/Class2Test.php';
require_once 'Package/Class1Test.php';
Result (test execution order):
1) Class1Test
2) Class2Test
3) Class3Test
4) Class3Test
5) Class2Test
6) Class1Test
I am using Netbeans 7.0beta to run the PHP 5.3.5 / PHPUnit 3.5.11 on windows 7.
I read the phpunit manual (http://www.phpunit.de/manual/3.5/en/organizing-tests.html) but i have no clue what i am doing wrong...
Please help.
PS: This problem can be solved by autoloading the classes.
PHPUnit 3.5 was released five years ago and has not been supported for four years. But even five years ago using PHPUnit_Framework_TestSuite objects to compose a test suite was no longer considered a good practice.
Please read the Getting Started article on the PHPUnit website as well as the chapter on organizing tests in the PHPUnit manual to learn how to properly organize your test suite.
Are you calling phpunit with the right parameters?
I have this setup, which works fine with suites.
/tests/
/tests/allTests.php
/tests/lib/
/tests/lib/libAllTests.php
/tests/lib/baseTest.php
/tests/lib/coreTest.php
/tests/lib/...
allTests.php:
require_once 'lib/libAllTests.php';
class AllTests
{
public static function suite()
{
$suite = new PHPUnit_Framework_TestSuite('Project');
$suite->addTestSuite('LibAllTests');
return $suite;
}
}
libAllTests.php:
require_once 'baseTest.php';
require_once 'coreTest.php';
class LibAllTests
{
public static function suite()
{
$suite = new PHPUnit_Framework_TestSuite('Lib');
$suite->addTestSuite('CoreTest');
$suite->addTestSuite('BaseTest');
return $suite;
}
}
From a command prompt I can call:
phpunit /tests/allTests.php: Runs all tests
phpunit /tests/lib/libAllTests.php: Runs all lib tests
phpunit /tests/lib/baseTest.php: Runs all base tests
phpunit /tests/*: Runs all tests
And in all four scenarios, the core tests are run before base tests, and no tests are repeated twice.
I'm using phpUnit 3.5.7.