How do I run a shell command from inside a Behat test? - laravel

I'm working on laravel 5 app and I need to create an artisan command. I'm using Behat as my testing framework. I know I can test the state of my database inside of behat. I want to run a command like"
php artisan my:command
from inside a behat step. How can I accomplish this?
Thanks

Inside your FeatureContext class:
/**
* #When I run :command
*/
public function iRun($command)
{
$this->output = shell_exec($command);
}
If you are using Symfony console component, take a look at https://gist.github.com/tPl0ch/6706427
You can even describe your commands like on https://gist.github.com/everzet/1683634.

I found a simple way to do this. Since I'm running an artisan command, I can use the Artisan facade.
/**
* #Given I run the artisan command :command with args :args
* #param $command
* #param $args
*/
public function iRunTheArtisanCommandWithArgs($command, $args)
{
\Artisan::call($command, [$args]);
}

Related

Laravel Schedule not triggering job

I do have a docker file runing a laravel app and some runners.
The schedule is triggering the command but it is not doing anything.
Whenever I try to run the command manually it works fine.
The command consulta_a1 dispatch a job that is suposed to fail, doing so the supervisor will log it on super.txt.
When the schedule run the command nothing happens, whenever I run the comand on the console it works as expected.
I configured my kernel in the following way:
protected $commands = [
Commands\ConsultaDfeA1Command::class
];
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')->hourly();
if (env("AMBIENTE") == "2") {
$schedule->command('consultar_a1')->dailyAt('12:23');
$schedule->command('consultar_a1')->dailyAt('12:28');
}
if (env("AMBIENTE") == "1") {
$schedule->command('consultar_a1')->cron('0 0,3,6,9,12,18,21 * * *');
}
}
/**
* Register the commands for the application.
*
* #return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
In this screenshot we can se that the scheduler is configured and that I ran the exact command that the schedule is suposed to work.
The cron triggered the schedule.
But whenever I check my supervisor jobs log just the manual actions were triggered.
Crontab -l:
* * * * * /usr/local/bin/php /var/www/artisan schedule:run 1>> /var/log/cron-log 2>&1
I have no idea what is happening and if any other infos are missing.
I know this is old but did you find a solution? I've the same probleme:
$schedule->command(...) and $schedule->exec(...) won't work, no error message, schedule says "Running scheduled command" but nothing happens.
on the other hand $schedule->call(function () {...} will work...
I suspect it has to do with the ovh shared hosting the script is run on but searched the internet for a week now and no solution.

How can I run in background command, which runs only in foreground?

I have the command, which works like php artisan queue:listen. And it can't work in background in common, but I have to add it to cron tab, but it does not work there. Does it possible to do something like php artisan schedule:run ? The most imortant that when I interrupt this command, all functionalyty will stop. What do I have to do in this situation?
Laravel has his own cron. First of all, you should add Laravel cron to Linux system cron
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
then you can add your commands to Laravel cron.
Laravel crons lives inside a file /app/Console/Kernel.php
the are should be inside function
protected function schedule(Schedule $schedule)
for example
protected function schedule(Schedule $schedule)
{
$schedule->command('emails:send Taylor --force')->cron('* * * * *');
}
But if you want your command run as a system process not as a cron you should use supervisors program(supervisord) or you can create for PHP command file a systemd service file and then run as if the are a normal systemd service and even manage this service through monit program in with web interface as well
If your php script is a process it means that the constructor method of class runs only ones when you start your script and if you red db data in the constructor that data in the script would be stale
Your process script should be process something like this
class OpenOrders extends Command
{
public function __construct()
{
parent::__construct();
}
public function handle()
{
$this->initTicker();
$this->updateBalances();
//the Process
while (true) {
//this is the right place to read DB data
$this->getAllOptions();
$this->openOrders = $this->getOpenOrders();
}
return 0;
}
}

No scheduled commands are ready to run | only in $schedule

Laravel Version: 5.7.25
PHP Version: 7.2.14
Database Driver & Version: MySQL 2ยช gen. 5.7
Hi, Sorry for the trouble, I have this problem in creating a scheduled command.
Description:
In our crontab -e user we have inserted the following on Debian:
* * * * * cd /var/www/myfolder.com/ && php artisan schedule:run >> crontab.laravel
We have correctly entered the schedule function as follows:
app/console/kernel.php
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
// 'App\Console\Commands\HelpCenter',
Commands\HelpCenter::class
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('elena:help')->everyMinute();
}
/**
* Register the commands for the application.
*
* #return void
*/
protected function commands()
{
$this->load(__DIR__ . '/Commands');
require base_path('routes/console.php');
}
}
but the result continues to be No scheduled commands are ready to run
we tried all the combinations impossible but nothing.
If we uncomment the function Artisan call working, the script is executed
Try to force command crontab -e
To better understand where the problem lies We have added a crontab directly with the command without going through the schedule as :
* * * * * cd /var/www/myfolder.com/ && php artisan elena:help >> crontab.laravel
This command runs perfectly every minute so we can not figure out where the problem is.
if you have the patience to give us some advice we will be happy. good day
I copy this here because this solved my issue. It's #piscator comment above.
"Did you run php artisan cache:clear? There might be a schedule file cached in your storage/framework folder."
EDIT:
This issue was giving me a lot of trouble. I'm using Laravel 5.8 and I couldn't make it work with ->withoutOverlapping(); The task will die after a while without apparent reasons and then the cron job couldn't start it again because ->withoutOverlapping() was preventing it.
Finally I found a solution here:
Basically, instead of using Laravel's ->withoutOverlapping(), you check yourself if the task is already running.
// start the queue worker, if its not running
$command = "queue:work --queue=high,email,default,low --tries=3 --delay=3";
if (!$this->osProcessIsRunning($command)) {
$schedule->command($command)->everyMinute()
->runInBackground()
->appendOutputTo(storage_path('logs/queue.log'));
}
// function for checking if the task is running
protected function osProcessIsRunning($needle)
{
// get process status. the "-ww"-option is important to get the full output!
exec('ps aux -ww', $process_status);
// search $needle in process status
$result = array_filter($process_status, function($var) use ($needle) {
return strpos($var, $needle);
});
// if the result is not empty, the needle exists in running processes
if (!empty($result)) {
return true;
}
return false;
}
Thanks to #henryonsoftware for the solution
I don't know if I am late, but I have a solution for you.
JUST ADD THE TIMEZONE IN THE SCHEDULE METHOD.
it will start working well.
Example:
$schedule->command('tenam:before')
->dailyAt('22:28')->timezone('Asia/Kolkata');

Check if input is from console

I want to share a variable of my views with:
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
\Schema::defaultStringLength(191);
$customers = Customer::get();
\View::share('customers', $customers);
}
}
it works as expected, but when I want to migrate my tables via artisan it throws an error, that the table for customers was not found because it is checked BEFORE the migration starts. So I need something like
if(!artisan_request) {
//request to laravel is via web and not artisan
}
But I haven't found anything in the documentation.
You can check if you are running in the console by using
app()->runningInConsole()
Underneath that, all it does is check the interface type
return php_sapi_name() == 'cli' || php_sapi_name() == 'phpdbg'
You can find more on the PHP Docs site
To detect whether the app is running in console, you can do something like this:
use Illuminate\Support\Facades\App;
if(App::runningInConsole())
{
// app is running in console
}
See, illuminate/Foundation/Application.php:520

cron scheduler in laravel 4

I am trying to set cron for a command or controller action but it seemed to be not working for me. Please see below what I have tried
I have been trying to set up scheduler as per your instructions with no result.
When I try:
1. /usr/local/bin/php /home/mysite/public_html/protected/app/start/artisan cron:run it gives error
Could not open input file: /home/mysite/public_html/protected/app/start/artisan
2. /usr/local/bin/php /home/mysite/public_html/protected/app/controllers/TestController.php
it gives error Fatal error: Class 'BaseController' not found in
3. /usr/local/bin/php -q /home/mysite/public_html/protected/app/start/artisan cron:run
Error-Could not open input file:
4. php /var/www/com/mysite.com/artisan cron:run
Status: 404 Not Found No input file specified.
/usr/local/bin/php home/opendesk/public_html/protected/app/start/artisan.php and in artisan.php I do like Artisan::add(new CronRunCommand);
Error Fatal error: Class 'Artisan' not found
/usr/local/bin/php /home/opendesk/public_html/protected/app/start/artisan.php
when in artisan.php I change it to $artisan->add(new CronRunCommand);
Error Fatal error: Call to a member function add() on a non-object
None of it seems to work. I have been read many SO and google posts but cant find a solution to this. hoping to get some help here
At first. Task Scheduling not available in laravel 4, you need use newest version.
At second. What a path /home/mysite/public_html/protected/app/start/artisan? Can you show application folder structure?
However artisan its file in application root folder in default installation. For sample - my application placed in \var\www\myaplication then artisan placed in \var\www\myaplication\artisan. And i call this php \var\www\myaplication\artisan or better, change current dir to cd \var\www\myaplication and run php artisan.
At trith artisan cron can not prepare controller method. You need create a cron task in file App\Console\Kernel
<?php
namespace App\Console;
use DB;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
\App\Console\Commands\Inspire::class,
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->call(function () {
DB::table('recent_users')->delete();
})->daily();
}
}
For more details read documenation this very useful!

Resources