~ballot/wordpress/openstack-objectstorage-breaking-insight

« back to all changes in this revision

Viewing changes to vendor/guzzlehttp/guzzle/tests/Server.php

  • Committer: Jacek Nykis
  • Date: 2015-02-11 15:35:31 UTC
  • Revision ID: jacek.nykis@canonical.com-20150211153531-hmy6zi0ov2qfkl0b
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
 
 
3
namespace GuzzleHttp\Tests;
 
4
 
 
5
use GuzzleHttp\Client;
 
6
use GuzzleHttp\Message\MessageFactory;
 
7
use GuzzleHttp\Message\ResponseInterface;
 
8
 
 
9
/**
 
10
 * The Server class is used to control a scripted webserver using node.js that
 
11
 * will respond to HTTP requests with queued responses.
 
12
 *
 
13
 * Queued responses will be served to requests using a FIFO order.  All requests
 
14
 * received by the server are stored on the node.js server and can be retrieved
 
15
 * by calling {@see Server::received()}.
 
16
 *
 
17
 * Mock responses that don't require data to be transmitted over HTTP a great
 
18
 * for testing.  Mock response, however, cannot test the actual sending of an
 
19
 * HTTP request using cURL.  This test server allows the simulation of any
 
20
 * number of HTTP request response transactions to test the actual sending of
 
21
 * requests over the wire without having to leave an internal network.
 
22
 */
 
23
class Server
 
24
{
 
25
    const REQUEST_DELIMITER = "\n----[request]\n";
 
26
 
 
27
    /** @var Client */
 
28
    private static $client;
 
29
 
 
30
    public static $started;
 
31
    public static $url = 'http://127.0.0.1:8125/';
 
32
    public static $port = 8125;
 
33
 
 
34
    /**
 
35
     * Flush the received requests from the server
 
36
     * @throws \RuntimeException
 
37
     */
 
38
    public static function flush()
 
39
    {
 
40
        self::start();
 
41
 
 
42
        return self::$client->delete('guzzle-server/requests');
 
43
    }
 
44
 
 
45
    /**
 
46
     * Queue an array of responses or a single response on the server.
 
47
     *
 
48
     * Any currently queued responses will be overwritten.  Subsequent requests
 
49
     * on the server will return queued responses in FIFO order.
 
50
     *
 
51
     * @param array|ResponseInterface $responses A single or array of Responses
 
52
     *                                           to queue.
 
53
     * @throws \Exception
 
54
     */
 
55
    public static function enqueue($responses)
 
56
    {
 
57
        static $factory;
 
58
        if (!$factory) {
 
59
            $factory = new MessageFactory();
 
60
        }
 
61
 
 
62
        self::start();
 
63
 
 
64
        $data = [];
 
65
        foreach ((array) $responses as $response) {
 
66
 
 
67
            // Create the response object from a string
 
68
            if (is_string($response)) {
 
69
                $response = $factory->fromMessage($response);
 
70
            } elseif (!($response instanceof ResponseInterface)) {
 
71
                throw new \Exception('Responses must be strings or Responses');
 
72
            }
 
73
 
 
74
            $headers = array_map(function ($h) {
 
75
                return implode(' ,', $h);
 
76
            }, $response->getHeaders());
 
77
 
 
78
            $data[] = [
 
79
                'statusCode'   => $response->getStatusCode(),
 
80
                'reasonPhrase' => $response->getReasonPhrase(),
 
81
                'headers'      => $headers,
 
82
                'body'         => base64_encode((string) $response->getBody())
 
83
            ];
 
84
        }
 
85
 
 
86
        self::getClient()->put('guzzle-server/responses', [
 
87
            'body' => json_encode($data)
 
88
        ]);
 
89
    }
 
90
 
 
91
    /**
 
92
     * Get all of the received requests
 
93
     *
 
94
     * @param bool $hydrate Set to TRUE to turn the messages into
 
95
     *      actual {@see RequestInterface} objects.  If $hydrate is FALSE,
 
96
     *      requests will be returned as strings.
 
97
     *
 
98
     * @return array
 
99
     * @throws \RuntimeException
 
100
     */
 
101
    public static function received($hydrate = false)
 
102
    {
 
103
        if (!self::$started) {
 
104
            return [];
 
105
        }
 
106
 
 
107
        $response = self::getClient()->get('guzzle-server/requests');
 
108
        $data = array_filter(explode(self::REQUEST_DELIMITER, (string) $response->getBody()));
 
109
        if ($hydrate) {
 
110
            $factory = new MessageFactory();
 
111
            $data = array_map(function ($message) use ($factory) {
 
112
                return $factory->fromMessage($message);
 
113
            }, $data);
 
114
        }
 
115
 
 
116
        return $data;
 
117
    }
 
118
 
 
119
    /**
 
120
     * Stop running the node.js server
 
121
     */
 
122
    public static function stop()
 
123
    {
 
124
        if (self::$started) {
 
125
            self::getClient()->delete('guzzle-server');
 
126
        }
 
127
 
 
128
        self::$started = false;
 
129
    }
 
130
 
 
131
    public static function wait($maxTries = 5)
 
132
    {
 
133
        $tries = 0;
 
134
        while (!self::isListening() && ++$tries < $maxTries) {
 
135
            usleep(100000);
 
136
        }
 
137
 
 
138
        if (!self::isListening()) {
 
139
            throw new \RuntimeException('Unable to contact node.js server');
 
140
        }
 
141
    }
 
142
 
 
143
    private static function start()
 
144
    {
 
145
        if (self::$started) {
 
146
            return;
 
147
        }
 
148
 
 
149
        if (!self::isListening()) {
 
150
            exec('node ' . __DIR__ . \DIRECTORY_SEPARATOR . 'server.js '
 
151
                . self::$port . ' >> /tmp/server.log 2>&1 &');
 
152
            self::wait();
 
153
        }
 
154
 
 
155
        self::$started = true;
 
156
    }
 
157
 
 
158
    private static function isListening()
 
159
    {
 
160
        try {
 
161
            self::getClient()->get('guzzle-server/perf', [
 
162
                'connect_timeout' => 5,
 
163
                'timeout'         => 5
 
164
            ]);
 
165
            return true;
 
166
        } catch (\Exception $e) {
 
167
            return false;
 
168
        }
 
169
    }
 
170
 
 
171
    private static function getClient()
 
172
    {
 
173
        if (!self::$client) {
 
174
            self::$client = new Client(['base_url' => self::$url]);
 
175
        }
 
176
 
 
177
        return self::$client;
 
178
    }
 
179
}