Thanks to visit codestin.com
Credit goes to github.com

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
31 changes: 27 additions & 4 deletions .github/workflows/conformance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,48 @@ jobs:
go-version: '1.15'

- name: Run HTTP conformance tests
uses: GoogleCloudPlatform/functions-framework-conformance/[email protected].0
uses: GoogleCloudPlatform/functions-framework-conformance/[email protected].1
env:
FUNCTION_TARGET: 'httpFunc'
FUNCTION_SIGNATURE_TYPE: 'http'
FUNCTION_SOURCE: ${{ github.workspace }}/tests/conformance/index.php
with:
version: 'v1.0.0'
version: 'v1.2.1'
functionType: 'http'
useBuildpacks: false
cmd: "'php -S localhost:8080 router.php'"

- name: Run Declarative HTTP conformance tests
uses: GoogleCloudPlatform/functions-framework-conformance/[email protected]
env:
FUNCTION_TARGET: 'declarativeHttpFunc'
FUNCTION_SOURCE: ${{ github.workspace }}/tests/conformance/index.php
with:
version: 'v1.2.1'
functionType: 'http'
useBuildpacks: false
cmd: "'php -S localhost:8080 router.php'"

- name: Run CloudEvent conformance tests
uses: GoogleCloudPlatform/functions-framework-conformance/[email protected].0
uses: GoogleCloudPlatform/functions-framework-conformance/[email protected].1
env:
FUNCTION_TARGET: 'cloudEventFunc'
FUNCTION_SIGNATURE_TYPE: 'cloudevent'
FUNCTION_SOURCE: ${{ github.workspace }}/tests/conformance/index.php
with:
version: 'v1.0.0'
version: 'v1.2.1'
functionType: 'cloudevent'
useBuildpacks: false
validateMapping: true
cmd: "'php -S localhost:8080 router.php'"

- name: Run Declarative CloudEvent conformance tests
uses: GoogleCloudPlatform/functions-framework-conformance/[email protected]
env:
FUNCTION_TARGET: 'declarativeCloudEventFunc'
FUNCTION_SOURCE: ${{ github.workspace }}/tests/conformance/index.php
with:
version: 'v1.2.1'
functionType: 'cloudevent'
useBuildpacks: false
validateMapping: true
Expand Down
7 changes: 1 addition & 6 deletions router.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

/**
* Copyright 2019 Google LLC.
*
Expand Down Expand Up @@ -49,12 +50,6 @@
if (false === $target) {
throw new RuntimeException('FUNCTION_TARGET is not set');
}
if (!is_callable($target)) {
throw new InvalidArgumentException(sprintf(
'Function target is not callable: "%s"',
$target
));
}

$signatureType = getenv('FUNCTION_SIGNATURE_TYPE', true) ?: 'http';

Expand Down
52 changes: 52 additions & 0 deletions run_conformance_tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/bin/bash
# Runs the conformance tests locally from https://github.com/GoogleCloudPlatform/functions-framework-conformance.
# Requires Go 1.16+ to run.
#
# Servers may fail to shutdown between tests on error, leaving port 8080 bound.
# You can see what's running on port 8080 by running `lsof -i :8080`. You can
# run `kill -9 <PID>` to terminate a process.
#
# USAGE:
# ./run_conformance_tests.sh [client_version]
#
# client_version (optional):
# The version of the conformance tests client to use, formatted as "vX.X.X".
# Defaults to the latest version of the repo, which may be ahead of the
# latest release.

CLIENT_VERSION=$1
if [ $CLIENT_VERSION ]; then
CLIENT_VERSION="@$CLIENT_VERSION"
else
echo "Defaulting to latest client."
echo "Use './run_conformance_tests vX.X.X' to specify a specific release version."
CLIENT_VERSION="@latest"
fi

function print_header() {
echo
echo "========== $1 =========="
}

# Fail if any command fails
set -e

print_header "INSTALLING CLIENT$CLIENT_VERSION"
echo "Note: only works with Go 1.16+ by default, see run_conformance_tests.sh for more information."
# Go install @version only works on go 1.16+, if using a lower Go version
# replace command with:
# go get github.com/GoogleCloudPlatform/functions-framework-conformance/client$CLIENT_VERSION && go install github.com/GoogleCloudPlatform/functions-framework-conformance/client
go install github.com/GoogleCloudPlatform/functions-framework-conformance/client$CLIENT_VERSION
echo "Done installing client$CLIENT_VERSION"

print_header "HTTP CONFORMANCE TESTS"
FUNCTION_TARGET='httpFunc' FUNCTION_SIGNATURE_TYPE='http' FUNCTION_SOURCE=$(realpath tests/conformance/index.php) client -buildpacks=false -type=http -cmd='php -S localhost:8080 router.php' -start-delay 5 -validate-mapping=true

print_header "DECLARATIVE HTTP CONFORMANCE TESTS"
FUNCTION_TARGET='declarativeHttpFunc' FUNCTION_SIGNATURE_TYPE= FUNCTION_SOURCE=$(realpath tests/conformance/index.php) client -buildpacks=false -type=http -cmd='php -S localhost:8080 router.php' -start-delay 5 -validate-mapping=true

print_header "CLOUDEVENT CONFORMANCE TESTS"
FUNCTION_TARGET='cloudEventFunc' FUNCTION_SIGNATURE_TYPE='cloudevent' FUNCTION_SOURCE=$(realpath tests/conformance/index.php) client -buildpacks=false -type=cloudevent -cmd='php -S localhost:8080 router.php' -start-delay 5 -validate-mapping=true

print_header "DECLARATIVE CLOUDEVENT CONFORMANCE TESTS"
FUNCTION_TARGET='declarativeCloudEventFunc' FUNCTION_SIGNATURE_TYPE= FUNCTION_SOURCE=$(realpath tests/conformance/index.php) client -buildpacks=false -type=cloudevent -cmd='php -S localhost:8080 router.php' -start-delay 5 -validate-mapping=true
16 changes: 15 additions & 1 deletion src/CloudEventFunctionWrapper.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

/**
* Copyright 2020 Google LLC.
*
Expand All @@ -17,6 +18,7 @@

namespace Google\CloudFunctions;

use CloudEvents\V1\CloudEventInterface;
use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
Expand All @@ -27,6 +29,8 @@ class CloudEventFunctionWrapper extends FunctionWrapper
private const TYPE_BINARY = 2;
private const TYPE_STRUCTURED = 3;

private bool $marshalToCloudEventInterface;

// These are CloudEvent context attribute names that map to binary mode
// HTTP headers when prefixed with 'ce-'. 'datacontenttype' is notably absent
// from this list because the header 'ce-datacontenttype' is not permitted;
Expand All @@ -42,6 +46,12 @@ class CloudEventFunctionWrapper extends FunctionWrapper
'time'
];

public function __construct(callable $function, bool $marshalToCloudEventInterface = false)
{
$this->marshalToCloudEventInterface = $marshalToCloudEventInterface;
parent::__construct($function);
}

public function execute(ServerRequestInterface $request): ResponseInterface
{
$body = (string) $request->getBody();
Expand Down Expand Up @@ -89,6 +99,10 @@ public function execute(ServerRequestInterface $request): ResponseInterface
], 'invalid event type');
}

if ($this->marshalToCloudEventInterface) {
$cloudevent = new CloudEventSdkCompliant($cloudevent);
}

call_user_func($this->function, $cloudevent);
return new Response();
}
Expand Down Expand Up @@ -134,6 +148,6 @@ private function fromBinaryRequest(

protected function getFunctionParameterClassName(): string
{
return CloudEvent::class;
return $this->marshalToCloudEventInterface ? CloudEventInterface::class : CloudEvent::class;
}
}
6 changes: 5 additions & 1 deletion src/CloudEventSdkCompliant.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ public function getSubject(): ?string
}
public function getTime(): ?DateTimeImmutable
{
return DateTimeImmutable::createFromFormat(DateTimeInterface::RFC3339_EXTENDED, $this->cloudevent->getTime());
$time = DateTimeImmutable::createFromFormat(DateTimeInterface::RFC3339_EXTENDED, $this->cloudevent->getTime());
if ($time === false) {
return null;
}
return $time;
}
public function getExtension(string $attribute)
{
Expand Down
2 changes: 1 addition & 1 deletion src/FunctionWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ abstract class FunctionWrapper

protected $function;

public function __construct(callable $function, array $signature = null)
public function __construct(callable $function)
{
$this->validateFunctionSignature(
$this->getFunctionReflection($function)
Expand Down
37 changes: 37 additions & 0 deletions src/FunctionsFramework.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?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.
*/

namespace Google\CloudFunctions;

class FunctionsFramework
{
private function __construct()
{
// Constructor disabled because this class should only be used statically.
}

public static function http(string $name, callable $fn)
{
Invoker::registerFunction($name, new HttpFunctionWrapper($fn));
}

public static function cloudEvent(string $name, callable $fn)
{
Invoker::registerFunction($name, new CloudEventFunctionWrapper($fn, true));
}
}
5 changes: 0 additions & 5 deletions src/HttpFunctionWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@

class HttpFunctionWrapper extends FunctionWrapper
{
public function __construct(callable $function)
{
parent::__construct($function);
}

public function execute(ServerRequestInterface $request): ResponseInterface
{
$path = $request->getUri()->getPath();
Expand Down
61 changes: 44 additions & 17 deletions src/Invoker.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

/**
* Copyright 2019 Google LLC.
*
Expand Down Expand Up @@ -28,31 +29,45 @@ class Invoker
{
private $function;
private $errorLogFunc;
private static $registeredFunction = [];

/**
* @param callable $target The callable to be invoked
* @param string $signatureType The signature type of the target callable,
* either "event" or "http".
* @param array|string $target The callable to be invoked.
* @param string|null $signatureType The signature type of the target callable,
* either "cloudevent" or "http". If null,
* env var `FUNCTION_SIGNATURE_TYPE` is used.
*/
public function __construct(callable $target, string $signatureType)
public function __construct($target, ?string $signatureType = null)
{
if ($signatureType === 'http') {
$this->function = new HttpFunctionWrapper($target);
} elseif (
$signatureType === 'event'
|| $signatureType === 'cloudevent'
) {
$this->function = new CloudEventFunctionWrapper($target);
if (is_string($target) && isset(self::$registeredFunction[$target])) {
$this->function = self::$registeredFunction[$target];
} else {
throw new InvalidArgumentException(sprintf(
'Invalid signature type: "%s"',
$signatureType
));
if (!is_callable($target)) {
throw new InvalidArgumentException(sprintf(
'Function target is not callable: "%s"',
$target
));
}

if ($signatureType === 'http') {
$this->function = new HttpFunctionWrapper($target);
} elseif (
$signatureType === 'event'
|| $signatureType === 'cloudevent'
) {
$this->function = new CloudEventFunctionWrapper($target, false);
} else {
throw new InvalidArgumentException(sprintf(
'Invalid signature type: "%s"',
$signatureType
));
}
}

$this->errorLogFunc = function (string $error) {
fwrite(fopen('php://stderr', 'wb'), json_encode([
'message' => $error,
'severity' => 'error'
'message' => $error,
'severity' => 'error'
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
};
}
Expand All @@ -79,4 +94,16 @@ public function handle(
]);
}
}

/**
* Static registry for declaring functions. Internal only
*
* @internal
* @param string $name The name of the registered function
* @param FunctionWrapper $function The mapped FunctionWrapper instance
*/
public static function registerFunction(string $name, FunctionWrapper $function)
{
self::$registeredFunction[$name] = $function;
}
}
Loading