Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions functions/concepts_build_extension/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Files from phpize
ext/Makefile.global
ext/acinclude.m4
ext/aclocal.m4
ext/autom4te.cache/
ext/config.guess
ext/config.h.in
ext/config.sub
ext/configure
ext/configure.ac
ext/install-sh
ext/ltmain.sh
ext/missing
ext/mkinstalldirs
ext/run-tests.php

# Files from ./configure
ext/Makefile
ext/Makefile.fragments
ext/Makefile.objects
ext/config.h
ext/config.log
ext/config.nice
ext/config.status
ext/libtool

# Files from make
ext/.libs/
ext/modules/
ext/my_custom_extension.la
ext/my_custom_extension.lo

# The custom PHP extension
my_custom_extension.so

13 changes: 13 additions & 0 deletions functions/concepts_build_extension/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"require": {
"google/cloud-functions-framework": "^0.7.1"
},
"scripts": {
"gcp-build": "cd ext && phpize --clean && phpize && ./configure && make && cp modules/my_custom_extension.so ..",
"start": [
"@gcp-build",
"Composer\\Config::disableProcessTimeout",
"FUNCTION_TARGET=helloBuildExtension php -d 'extension=./my_custom_extension.so' -S localhost:${PORT:-8080} vendor/bin/router.php"
]
}
}
5 changes: 5 additions & 0 deletions functions/concepts_build_extension/ext/config.m4
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
PHP_ARG_ENABLE(my_custom_extension, Whether to enable the MyCustomExtension extension, [ --enable-my-custom-extension Enable MyCustomExtension])

if test "$MY_CUSTOM_EXTENSION" != "no"; then
PHP_NEW_EXTENSION(my_custom_extension, my_custom_extension.c, $ext_shared)
fi
34 changes: 34 additions & 0 deletions functions/concepts_build_extension/ext/my_custom_extension.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// include the PHP API itself
#include <php.h>
// include the extension header
#include "my_custom_extension.h"

// register the "helloworld_from_extension" function to the PHP API
zend_function_entry my_custom_extension_functions[] = {
PHP_FE(helloworld_from_extension, NULL)
{NULL, NULL, NULL}
};

// some information about our module
zend_module_entry my_custom_extension_module_entry = {
STANDARD_MODULE_HEADER,
PHP_MY_CUSTOM_EXTENSION_EXTNAME,
my_custom_extension_functions,
NULL,
NULL,
NULL,
NULL,
NULL,
PHP_MY_CUSTOM_EXTENSION_VERSION,
STANDARD_MODULE_PROPERTIES
};

// use a macro to output additional C code, to make ext dynamically loadable
ZEND_GET_MODULE(my_custom_extension)

// Implement our "Hello World" function, which returns a string
PHP_FUNCTION(helloworld_from_extension) {
zval val;
ZVAL_STRING(&val, "Hello World! (from my_custom_extension.so)\n");
RETURN_STR(Z_STR(val));
}
6 changes: 6 additions & 0 deletions functions/concepts_build_extension/ext/my_custom_extension.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// module constants
#define PHP_MY_CUSTOM_EXTENSION_EXTNAME "my_custom_extension"
#define PHP_MY_CUSTOM_EXTENSION_VERSION "0.0.1"

// the function to be exported
PHP_FUNCTION(helloworld_from_extension);
29 changes: 29 additions & 0 deletions functions/concepts_build_extension/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php
/**
* Copyright 2021 Google LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* To use this, set the following environment variables:
* FUNCTION_TARGET=helloHttp
* FUNCTION_EVENT_TYPE=http
*/

use Psr\Http\Message\ServerRequestInterface;

function helloBuildExtension(ServerRequestInterface $request)
{
return helloworld_from_extension();
}
2 changes: 2 additions & 0 deletions functions/concepts_build_extension/php.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
;enable our custom extension
extension=/workspace/my_custom_extension.so
34 changes: 34 additions & 0 deletions functions/concepts_build_extension/phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2021 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<phpunit bootstrap="../../testing/bootstrap.php" convertWarningsToExceptions="false">
<testsuites>
<testsuite name="Cloud Functions Build Step Test Suite">
<directory>test</directory>
</testsuite>
</testsuites>
<logging>
<log type="coverage-clover" target="build/logs/clover.xml"/>
</logging>
<filter>
<whitelist>
<directory suffix=".php">.</directory>
<exclude>
<directory>./vendor</directory>
</exclude>
</whitelist>
</filter>
</phpunit>
59 changes: 59 additions & 0 deletions functions/concepts_build_extension/test/DeployTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php
/**
* Copyright 2021 Google LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

declare(strict_types=1);

namespace Google\Cloud\Samples\Functions\ConceptsBuildExtension\Test;

use Google\Cloud\TestUtils\CloudFunctionDeploymentTrait;
use PHPUnit\Framework\TestCase;

/**
* Class DeployTest.
*
* This test is not run by the CI system.
*
* To skip deployment of a new function, run with "GOOGLE_SKIP_DEPLOYMENT=true".
* To skip deletion of the tested function, run with "GOOGLE_KEEP_DEPLOYMENT=true".
* @group deploy
*/
class DeployTest extends TestCase
{
use CloudFunctionDeploymentTrait;

private static $entryPoint = 'helloBuildExtension';

public function testFunction(): void
{
// Send a request to the function.
$resp = $this->client->get('', [
// Uncomment and CURLOPT_VERBOSE debug content will be sent to stdout.
// 'debug' => true
]);

// Assert status code.
$this->assertEquals('200', $resp->getStatusCode());

// Assert function output.
$output = trim((string) $resp->getBody());
// Failures often lead to a large HTML page in the response body.
$this->assertEquals(
'Hello World! (from my_custom_extension.so)',
$output
);
}
}
76 changes: 76 additions & 0 deletions functions/concepts_build_extension/test/SystemTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php
/**
* Copyright 2021 Google LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare(strict_types=1);

namespace Google\Cloud\Samples\Functions\ConceptsBuildExtension\Test;

use PHPUnit\Framework\TestCase;
use Google\Cloud\TestUtils\CloudFunctionLocalTestTrait;
use Google\Cloud\TestUtils\GcloudWrapper\CloudFunction;
use Google\Cloud\Utils\ExponentialBackoff;
use Symfony\Component\Process\Process;
use Symfony\Component\Process\PhpExecutableFinder;

/**
* Class SystemTest.
*/
class SystemTest extends TestCase
{
use CloudFunctionLocalTestTrait;

private static $entryPoint = 'helloBuildExtension';

public function testFunction(): void
{
// Send a request to the function.
$resp = $this->client->get('/');

// Assert status code.
$this->assertEquals('200', $resp->getStatusCode());

// Assert function output.
$output = trim((string) $resp->getBody());
$this->assertEquals(
'Hello World! (from my_custom_extension.so)',
$output
);
}

/**
* Start the development server based on the prepared function.
*
* We override this to run the "gcp-build" step and to enable the built
* extension when running the PHP build-in-web server.
*/
private static function doRun()
{
// Build the extension
$process = new Process(['composer', 'run-script', 'gcp-build']);
$process->start();

$backoff = new ExponentialBackoff($retries = 10);
$backoff->execute(function () use ($process) {
if ($process->isRunning()) {
throw new \Exception('waiting for "gcp-build" step to complete');
}
});

$phpBin = (new PhpExecutableFinder())->find();
$phpBin .= ' -d extension=\'./my_custom_extension.so\'';
return self::$fn->run([], CloudFunction::DEFAULT_PORT, $phpBin);
}
}