2016-10-20 3 views
8

Environment


Описание

Я пытаюсь запустить команду каждые 1 минуту, используя Laravel Task Scheduling.


Покушение

Я добавил эту строку в мою хронах НаФайлвкладку

* * * * * php artisan schedule:run >> /dev/null 2>&1

Вот мой /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\Inspire::class, 
    ]; 

    /** 
    * Define the application's command schedule. 
    * 
    * @param \Illuminate\Console\Scheduling\Schedule $schedule 
    * @return void 
    */ 
    protected function schedule(Schedule $schedule) 
    { 
     $schedule->command('inspire')->hourly(); 
     $schedule->command('echo "Happy New Year!" ')->everyMinute(); //<---- ADD HERE  } 
} 

Я добавил эту строку $schedule->command('echo "Happy New Year!" ')->everyMinute();


Вопрос

Как это проверить?

Как включить отображение эха?

Как я узнаю, что то, что я сделал, не так?


Я открываю любые предложения на данный момент.

Любые подсказки/предложения/помощь по этому поводу будут очень благодарны!

+1

То, что я делал, состоит в том, что каждая «команда» является фактически исполняемой командой ремесленника. Тогда вы можете проверить эту команду самостоятельно, чтобы убедиться, что она делает то, что вы хотите. Я не утруждаю себя проверкой того, что планировщик работает так, как ожидалось, bc, который предоставляется инфраструктурой, поэтому я могу предположить, что он работает. Единственное, что остается уязвимым, - это сделать опечатку или неправильно настроить планировщик, но если вы следуете документам, нет причин, по которым это не должно работать, и это будет просто тестирование bc, которому кто-то сказал, чтобы проверить все, кроме значения минимально .. не стесняйтесь – tam5

ответ

6

command() выполняет команду ремесленника. То, что вы пытаетесь достичь - выдавать команду на OS - делается exec('echo "Happy New Year!"')

Тестирование зависит от того, что вы хотите проверить:

  • ли планировщик (каждую минуту) работает?

В этом случае вам не обязательно. Он протестирован в исходном коде кода.

  • Выполняется ли команда?

Ну, вы можете вручную запустить php artisan schedule:run и посмотреть выход.

Планировщик не производит выход по умолчанию (>> /dev/null 2>&1). Однако вы можете перенаправить вывод запущенных скриптов в любой файл путем цепочки writeOutputTo() или appendOutputTo() (https://laravel.com/docs/5.1/scheduling#task-output).


Для более сложной логики, написать консольную команду вместо (https://laravel.com/docs/5.1/artisan#writing-commands) и использовать command() - таким образом, вы можете написать хороший, тестируемый код.

+0

Я обновляю свою строку '$ schedule-> command ('curl http://wttr.in/01851')->everyMinute()->sendOutputTo(public_path().'/ tasks/log.txt '); 'и получить мой журнал для экспорта, но в моем log.txt я его открываю, я вижу, что команда [InvalidArgumentException]« завиток »не определена. «Что я мог сделать неправильно? – ihue

+0

@ihue Функция команды запускает команды artisan, а не команды терминала для ОС. – tam5

+0

Как я писал выше, используйте '$ schedule-> exec()' вместо 'command()' :) – nXu

2

Если вы хотите выполнить модульное тестирование планирования событий, вы можете использовать этот пример. Он основан на умолчанию команды внушают:

public function testIsAvailableInTheScheduler() 
{ 
    /** @var \Illuminate\Console\Scheduling\Schedule $schedule */ 
    $schedule = app()->make(\Illuminate\Console\Scheduling\Schedule::class); 

    $events = collect($schedule->events())->filter(function (\Illuminate\Console\Scheduling\Event $event) { 
     return stripos($event->command, 'YourCommandHere'); 
    }); 

    if ($events->count() == 0) { 
     $this->fail('No events found'); 
    } 

    $events->each(function (\Illuminate\Console\Scheduling\Event $event) { 
     // This example is for hourly commands. 
     $this->assertEquals('0 * * * * *', $event->expression); 
    }); 
} 
0

Опираясь на ответ Михеля, я уже использовал методы, содержащиеся в Illuminate\Console\Scheduling\Event, чтобы проверить, если событие происходит из-за запуска на определенную дату.

Я высмеял текущую дату, используя Carbon::setTestNow(), так что любая логика, основанная на дате, в фильтрах when() и skip() будет вести себя так, как ожидалось.

use Tests\TestCase; 
use Illuminate\Console\Scheduling\Schedule; 
use Illuminate\Console\Scheduling\Event; 

use Cron\CronExpression; 
use Carbon\Carbon; 


class ScheduleTest extends TestCase { 


    public function testCompanyFeedbackSchedule() 
    { 
     $event = $this->getCommandEvent('your-command-signature'); 

     $test_date = Carbon::now()->startOfDay()->addHours(8); 

     for ($i=0; $i < 356; $i++) { 
      $test_date->addDay(); 
      Carbon::setTestNow($test_date); 

      // Run the when() & skip() filters 
      $filters_pass = $event->filtersPass($this->app); 
      // Test that the Cron expression passes 
      $date_passes = $this->isEventDue($event); 
      $will_run = $filters_pass && $date_passes; 

      // Should only run on first friday of month 
      if ($test_date->format('l') === 'Friday' && $test_date->weekOfMonth === 1) { 
       $this->assertTrue($will_run, 'Task should run on '. $test_date->toDateTimeString()); 
      } else { 
       $this->assertFalse($will_run, 'Task should not run on '. $test_date->toDateTimeString()); 
      } 
     } 
    } 


    /** 
    * Get the event matching the given command signature from the scheduler 
    * 
    * @param string $command_signature 
    * 
    * @return Illuminate\Console\Scheduling\Event 
    */ 
    private function getCommandEvent($command_signature) 
    { 
     $schedule = app()->make(Schedule::class); 

     $event = collect($schedule->events())->first(function (Event $event) use ($command_signature) { 
      return stripos($event->command, $command_signature); 
     }); 

     if (!$event) { 
      $this->fail('Event for '. $command_signature .' not found'); 
     } 

     return $event; 
    } 


    /** 
    * Determine if the Cron expression passes. 
    * 
    * Copied from the protected method Illuminate\Console\Scheduling\[email protected] 
    * 
    * @return bool 
    */ 
    private function isEventDue(Event $event) 
    { 
     $date = Carbon::now(); 

     if ($event->timezone) { 
      $date->setTimezone($event->timezone); 
     } 

     return CronExpression::factory($event->expression)->isDue($date->toDateTimeString()); 
    } 
} 
Смежные вопросы