1<?php
2
3/**
4 * Copyright 2015-2017 DataStax, Inc.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19namespace Cassandra;
20
21/**
22 * @requires extension cassandra
23 */
24class UuidTest extends \PHPUnit_Framework_TestCase
25{
26    public function testGeneratesUniqueUuids()
27    {
28        for ($i = 0; $i < 10000; $i++) {
29            $this->assertNotEquals((string) new Uuid(), (string) new Uuid());
30        }
31    }
32
33    /**
34     * @dataProvider equalTypes
35     */
36    public function testCompareEquals($value1, $value2)
37    {
38        $this->assertEquals($value1, $value2);
39        $this->assertTrue($value1 == $value2);
40    }
41
42    public function equalTypes()
43    {
44        return array(
45            array(new Uuid('2a5072fa-7da4-4ccd-a9b4-f017a3872304'), new Uuid('2a5072fa-7da4-4ccd-a9b4-f017a3872304')),
46        );
47    }
48
49    /**
50     * @dataProvider notEqualTypes
51     */
52    public function testCompareNotEquals($value1, $value2)
53    {
54        $this->assertNotEquals($value1, $value2);
55        $this->assertFalse($value1 == $value2);
56    }
57
58    public function notEqualTypes()
59    {
60        return array(
61            array(new Uuid('2a5072fa-7da4-4ccd-a9b4-f017a3872304'), new Uuid('3b5072fa-7da4-4ccd-a9b4-f017a3872304')),
62        );
63    }
64
65    /**
66     * Ensure UUIDs are unique for fork/child processes
67     *
68     * This test will ensure that the PHP driver is producing unique UUIDs for
69     * all child processes that get created during fork() operations in web
70     * servers (e.g. Apache, nginx, ...etc).
71     *
72     * @test
73     * @ticket PHP-115
74     */
75    public function testUniqueInChild() {
76        if (!function_exists("pcntl_fork")) {
77            $this->markTestSkipped("Unable to Execute testUniqueInChild Unit Test: pcntl_fork() does not exists");
78        } else {
79            // Create a PHP script to call within a PHPUnit test (exit call fails test)
80            $script = <<<EOF
81<?php
82// Get and open the file for appending child UUIDs
83\$uuidsFilename = \$_SERVER['argv'][1];
84\$numberOfForks = \$_SERVER['argv'][2];
85
86// Create requested children process; create UUIDs and append to a file
87\$children = array();
88foreach (range(1, \$numberOfForks) as \$i) {
89    // Create the child process
90    \$pid = pcntl_fork();
91
92    // Ensure the child process was create successfully
93    if (\$pid < 0) {
94        die("Unable to Create Fork: Unique UUID test cannot complete");
95    } else if (\$pid === 0) {
96        // Create a UUID and add it to the file
97        \$uuid = new \Cassandra\Uuid();
98        file_put_contents(\$uuidsFilename, \$uuid->uuid() . PHP_EOL, FILE_APPEND);
99
100        // Terminate child process
101        exit(0);
102    } else {
103        // Parent process: Add the process ID to force waiting on children
104        \$children[] = \$pid;
105    }
106}
107
108// Wait on each child process to finish
109foreach (\$children as \$pid) {
110    pcntl_waitpid(\$pid, \$status);
111}
112?>
113EOF;
114            $numProcesses = 64;
115
116            // Execute the PHP script passing in the filename for the UUIDs to be stored
117            $uuidsFilename = tempnam(sys_get_temp_dir(), "uuid");
118            $scriptFilename = tempnam(sys_get_temp_dir(), "uuid");
119            file_put_contents($scriptFilename, $script, FILE_APPEND);
120            exec(PHP_BINARY . " {$scriptFilename} {$uuidsFilename} $numProcesses");
121            unlink($scriptFilename);
122
123            // Get the contents of the file
124            $uuids = file($uuidsFilename);
125            unlink($uuidsFilename);
126
127            // Ensure all the UUIDs are unique
128            $this->assertEquals($numProcesses, count(array_unique($uuids)));
129        }
130    }
131}
132