PHPSpec: order of the class specs - php

I'm developing a HTTP server and for the first time I've decided to write the tests specs with PHPSpec, which is great.
I have two spec classes: spec\AppSpec and spec\RequestParserSpec.
Since the App is the interface between the server components and the outer world, it uses the RequestParser to parse the requests. So, in order to get the specs in AppSpec passing, the RequestParserSpec has to be ran before to check if the request parsing is working fine.
Here is the problem : $ phpspec run runs before AppSpec and then RequestParserSpec.
Is it possible to inverse that order? Presently, if RequestParser has a problem, AppSpec will fail without telling what's the root problem.
Yes, I know I can do phpspec run tests/spec/RequestParserSpec.php, then the others, but it would be more practical if this could be automated to run the tests in one pass.
suites:
myapp_suite:
namespace: MyApp
psr4_prefix: MyApp
spec_path: tests

You could substitute
$parser = new RequestParser(clone $this->baseRequest);
with this:
$parser = $this->requestParserFactory->createFromBaseRequest(clone $this->baseRequest);
then inject a RequestParserFactory, and you can then mock it in the spec.

Related

Injecting different implementations in console/web in Symfony 4

I have an interface UserIdProvider that has two implementations:
ConsoleUserIdProvider - it takes user id from CLI input option
RequestUserIdProvider - it comes from {userId} parameter in route
How should I configure Kernel to inject console implementation when I run CLI only, and how to use second one when it is regular request to web server?
I created separate ConsoleKernel extends Kernel for console.php where I load:
$loader->load($confDir . '/console_services.yml');
But unfortunately it overrides via cache in APP_ENV=prod mode regular Kernel where RequestUserIdProvider is supposed to be used.
Thanks in advance.
I figured it out. I should create new cli environment for that purpose.
I removed ConsoleKernel that loads custom yml file. It's not necessary.
I renamed console_services.yml to follow Symfony practice, which is supposed to be: services_cli.yml in my case. My console specific implementation is placed there.
I also changed console.php to disable debug mode in cli environment like for prod:
$notLikeProdEnv = !in_array($env, ["prod", "cli"], true);
$debug = ($_SERVER['APP_DEBUG'] ?? $notLikeProdEnv) && !$input->hasParameterOption(['--no-debug', '']);
Thanks to that when I run php console --env=cli I can see only commands specific to cli environment and also my ConsoleUserIdProvider implementation.

How to use MessageQueue feature of appserver.io inside existing laravel project

My existing Laravel project is such that all the tasks are executed sequentially. I have identified part of the code which can be run in parallel using PHP threads and can reduce the response time.
Instead of using pthreads, there was suggestion given that why not use appserver.io - which is fully multithreaded php server itself. One can use its MessageQueue feature, add all your job to this queue, and it will automatically fork worker threads. You don't have to manage anything.
I have already deployed existing Laravel app on appserver.io (copied project under /opt/appserver/webapps/ folder) but now I don't know how to use appserver's MessageQueue. My project uses psr-4, where as appserver is psr-0. Laravel has it's own DI and so does appserver.
All I want to do is, use appserver's MessageQueue to get more workers executing one function in parallel. I'm new to appserver and not sure how the directory structure should look like or what configuration I have do it. Any pointers will be helpful.
you can connect and send to the MessageQueue from within your Laravel application. First you've to install the client library appserver-io/messaging by adding "appserver-io/messaging" : "~1.0" to your composer.json. Then you can send a message with
$queue = MessageQueue::createQueue('pms/myQueue');
$connection = QueueConnectionFactory::createQueueConnection('my-laravel-app');
$session = $connection->createQueueSession();
$sender = $session->createSender($queue);
$sender->send(new StringMessage('Some String'));
assuming you've an application named my-laravel-app, that resides in the folder /opt/appserver/webapps/my-laravel-app and a MessageQueue called pms/myQueue, defined in a file META-INF/message-queues.xml. The file would look like
<?xml version="1.0" encoding="UTF-8"?>
<message-queues xmlns="http://www.appserver.io/appserver">
<message-queue type="MyReceiverClass">
<destination>pms/myQueue</destination>
</message-queue>
</message-queues>
In that example, the receiver class MyReceiverClass has to be available under /opt/appserver/webapps/my-laravel-app/META-INF/classes/MyLaravelApp/Receivers/MyReceiverClass for example.
A good start is the example application that comes with simple MessageQueue example running some simple import functionality.

Symfony ignore AppleDouble

I have a development server where I log in to (through ssh). Apple automatically creates the AppleDouble files/directories, which doesn't work well with Symfony. Every time I want to use a command (mostly doctrine:schema:update). I get AppleDouble errors about classes that don't exist.
Is there any way to tell Symfony to ignore those AppleDouble files?
I saw this issue on GitHub, but it's closed in favor of other issues, but I don't really know how to implement it.
(https://github.com/symfony/symfony/issues/5877)
Try to disable this in OSX itself:
defaults write com.apple.desktopservices DSDontWriteNetworkStores true
Found on this thread.
The folder is created not by Apple but by NAS which you are using probably. Look at this FAQ
So if you use Netatalk you should probably look at its docs. Same folders are created by RedyNAS. But the common pattern as I understood is to run command from terminal that #Valentas described. And then remove the folders recursively.
If you have to hold folders and make Symfony work you should modify the value of Finder::vcsPatterns. As the property is static you can add the following code to the app/console (or bin/console):
...
Finder::addVCSPattern('.AppleDouble');
$kernel = new AppKernel($env, $debug);
...

Symfony2 - what to watch out for when running a controller on the command line Vs browser

I'm about to start writing a Symfony2 application and I've come across some notes I must have written a while back about ensuring I write Symfony2 controllers with the fact it needs to be ran from the command line too.
Rather than bash out a load of controllers and seemingly be happy they work in a web browser, I want to ensure all controllers work on the command line too.
A lot of them will need to be ran from the command line, e.g. Cron Tasks etc.
(1) My notes tell me to insert this in AppKernel.php:
* This prevents a 'You cannot create a service ("request") of an inactive scope ("request")' error
<?php
class AppKernel extends Kernel
{
protected function initializeContainer() {
parent::initializeContainer();
if (PHP_SAPI == 'cli') {
$this->getContainer()->enterScope('request');
$this->getContainer()->set('request', new \Symfony\Component\HttpFoundation\Request(), 'request');
}
}
}
?>
(2) I've also got a pre-written request listener that runs various code on every request, and I'm aware the variables generated won't be used on the command line.
(3) I know that none of my Apache config will run (as it's not running inside Apache), and I also know that there's two php.ini files (CLI and Apache).
What else do I need to consider?
What else isn't available on the command line compared to a browser?
I would consider Console Component.
Symfony 2 has a build in interface for creating CLI based commands that will have the entire application bootstrapped, it's called Console Component.
Build out your cronjobs and tasks using this and you can use dependency injection to ensure you have all of the services you need.
I'm sure with some research you could figure out how to load a controller if necessary--controller forwarding or virtual?

Creating Cron Jobs in CakePHP 2.x

I have attempted to create a cron job in my CakePHP 2.x application. But all of the resources I have read online seem to be either doing it completely different to one another with little consistency or explain it in very complex terminology.
Basically I have created the following file MyShell.php in /app/Console/Command
<?php
class MyShell extends Shell {
public function sendEmail() {
App::uses('CakeEmail', 'Network/Email');
$email = new CakeEmail();
$email->from('cameron#driz.co.uk');
$email->to('cameron#driz.co.uk');
$email->subject('Test Email from Cron');
$result = $email->send('Hello from Cron');
}
}
?>
And I want to say run this code at midnight every night.
What do I do next? As the next part really confuses me! I have read on the Book at: http://book.cakephp.org/2.0/en/console-and-shells/cron-jobs.html that I should run some code in the terminal to make it do it at a certain time etc. And I can set these up using my hosting provider rather easily it seems.
But I'm rather confused about the Console directory. What should go in what folder in here: https://github.com/cakephp/cakephp/tree/master/app/Console
/Console/Command
/Console/Command/Tasks
/Console/Templates
Also noticed that many of the files are .php (e.g. my Shell file is also .php), but according to documentation I've read for Cron jobs, the executed files should be .sh?
Can anyone shed more light on this?
And what would the code be to call that command?
e.g. would presume this is incorrect: 0 0 * * * cd /domains/driz.co.uk/html/App && cake/Console MyShell sendEmail
Thanks
No. There is no way to do it just in PHP. But that doesn't matter, because crons are easy to set up.
In that article you linked to, you still have to set up a cron - the difference is just that you set up a single cron, that runs all your other crons - as opposed to setting up one cron per job. So, either way, you have to learn to create a cron.
The instructions depend on your server's operating system and also what host you're with. Some hosts will have a way to set up cron jobs through a GUI interface like cPanel or something, without you having to touch the terminal.
It's usually pretty easy to find instructions online for how to set up cron jobs with your host or server OS, but if you're having trouble, update your question with your host's name, and your server OS and version.
Also ---------------------------------
Often in cron jobs you'll be running a shell script (.sh). But don't worry about that for this case; your's will end in .php.
Re: the directory structure:
/Console/Command is where your new file should go.
If you're doing a lot of shell stuff, you may want to abstract common code out into the /Console/Command/Task folder. Read more about that here. This probably won't be needed in your case.
/Console/Command/Templates is where you can put custom templates for the Cake bake console - don't worry about that for now.
If I've only got a couple of cron jobs to run, then I create just one file called CronJobsShell.php, and put them all in there.
Really, you should read Cake's documentation on shells from start to end. It will give you a nice picture of how it all hangs together.
This can be done very easily by the following steps -:
1) Create a shell let's say HelloShell.php in Console/Command
<?php
class HelloShell extends AppShell
{
public function main()
{
//Your functionality here...
}
}
?>
This shell can be called by Console/cake hello
2) Write the command crontab-e .This will open up the default editor or the editor which you select Now as we want that our shell should run after at midnight write:-
0 0 * * * /PATH TO APP/Console/cake hello
For better understanding refer https://www.youtube.com/watch?v=ljgvo2jM234
Thanks!

Categories