src/TestUtils/CloudFunctionLocalTestTrait.php (68 lines of code) (raw):

<?php /** * Copyright 2020 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\Cloud\TestUtils; use Google\Cloud\TestUtils\GcloudWrapper\CloudFunction; use Google\CloudFunctions\CloudEvent; use GuzzleHttp\Client; /** * Trait CloudFunctionLocalTestTrait. * * Uses the function framework to run the function as a local service for system tests. */ trait CloudFunctionLocalTestTrait { use TestTrait; /** @var \GuzzleHttp\Client */ private $client; /** @var \Google\Cloud\TestUtils\GcloudWrapper\CloudFunction */ private static $fn; /** @var \Symfony\Component\Process\Process; */ private static $localhost; /** * Prepare and start the function in a local development server. * * @beforeClass */ public static function startFunction() { $props = [ 'projectId' => self::requireEnv('GOOGLE_PROJECT_ID') ]; if (isset(self::$entryPoint)) { $props['entryPoint'] = self::$entryPoint; } if (isset(self::$functionSignatureType)) { $props['functionSignatureType'] = self::$functionSignatureType; } self::$fn = CloudFunction::fromArray( self::initFunctionProperties($props) ); self::$localhost = self::doRun(); } /** * Start the development server based on the prepared function. * * Allows configuring server properties, for example: * * return self::$fn->run(['FOO' => 'bar'], '9090', '/usr/local/bin/php'); */ private static function doRun() { return self::$fn->run(); } /** * Customize startFunction properties. * * Example: * * $props['dir'] = 'path/to/function-dir'; * $props['region'] = 'us-west1'; * return $props; */ private static function initFunctionProperties(array $props = []) { return $props; } /** * Set up the client. * * @before */ public function setUpClient() { $baseUrl = self::$fn->getLocalBaseUrl(); $this->client = new Client([ 'base_uri' => $baseUrl, 'http_errors' => false ]); } /** * Stop the function. * * @afterClass */ public static function stopFunction() { self::$fn->stop(); } /** * Make a request using a cloud event * * Example: * * $this->request(CloudEvent::fromArray($params)); */ private function request(CloudEvent $cloudevent, array $params = []) { $cloudEventHeaders = array_filter([ 'ce-id' => $cloudevent->getId(), 'ce-source' => $cloudevent->getSource(), 'ce-specversion' => $cloudevent->getSpecVersion(), 'ce-type' => $cloudevent->getType(), 'ce-datacontenttype' => $cloudevent->getDataContentType(), 'ce-dataschema' => $cloudevent->getDataSchema(), 'ce-subject' => $cloudevent->getSubject(), 'ce-time' => $cloudevent->getTime(), ]); return $this->client->request('POST', '/', array_merge_recursive( $params, [ 'json' => $cloudevent->getData(), 'headers' => $cloudEventHeaders, ] )); } }