17
17
18
18
namespace Google \Cloud \Samples \Run \MCHelloPHPNginx ;
19
19
20
- use Google \Auth \ApplicationDefaultCredentials ;
21
20
use Google \Cloud \TestUtils \DeploymentTrait ;
22
21
use Google \Cloud \TestUtils \EventuallyConsistentTestTrait ;
23
22
use Google \Cloud \TestUtils \GcloudWrapper \CloudRun ;
24
23
use Google \Cloud \TestUtils \TestTrait ;
25
- use GuzzleHttp \Client ;
26
- use GuzzleHttp \HandlerStack ;
27
24
use PHPUnit \Framework \TestCase ;
28
25
29
26
/**
@@ -36,107 +33,143 @@ class MCNginxTest extends TestCase
36
33
use EventuallyConsistentTestTrait;
37
34
use TestTrait;
38
35
39
- /** @var \Google\Cloud\TestUtils\GcloudWrapper\CloudRun */
40
- private static $ nginxService ;
41
- private static $ phpService ;
42
-
43
36
/** @var string */
44
37
private static $ projectId ;
45
38
private static $ region ;
46
- private static $ versionId ;
47
39
private static $ repoName ;
40
+ private static $ mcServiceName ;
41
+ private static $ mcService ;
48
42
private static $ nginxImage ;
49
43
private static $ appImage ;
50
44
45
+
51
46
/**
52
- * Set up Artifact Registry image tags refs and declare Cloud Run services
47
+ * Execute given cmd
48
+ *
49
+ * Note: The use of exec() outside of the usual CloudRun stub class deploy() pattern is intentional
50
+ * as the feature is in public preview. If more php multi-container samples get added, this should be
51
+ * refactored to make `gcloud run services replace ...` reusable across samples
52
+ */
53
+ private static function execCmd ($ cmd = '' , $ output = null , $ retvalue = 3 )
54
+ {
55
+ if (false === exec ($ cmd , $ output , $ retvalue )) {
56
+ return false ;
57
+ }
58
+ return true ;
59
+ }
60
+
61
+ /**
62
+ * Set up test leveraged variabled and establish Artifact Registry image tags refs
53
63
*/
54
64
public static function setUpDeploymentVars ()
55
65
{
56
- $ projectId = self ::requireEnv ('GOOGLE_PROJECT_ID ' );
57
- $ region = getenv ('REGION ' ) ?: 'us-west1 ' ;
58
- $ repoName = getenv ('REPO_NAME ' ) ?: 'cloud-run-source-deploy ' ;
59
- $ versionId = getenv ('GOOGLE_VERSION_ID ' ) ?: sprintf ('hellophpnginx-%s ' , time ());
66
+ $ timestamp = time ();
67
+ self ::$ projectId = self ::requireEnv ('GOOGLE_PROJECT_ID ' );
68
+ self ::$ region = getenv ('REGION ' ) ?: 'us-west1 ' ;
69
+ self ::$ repoName = getenv ('REPO_NAME ' ) ?: 'cloud-run-source-deploy ' ;
70
+ self ::$ mcServiceName = sprintf ('hello-php-nginx-mc-%s ' , $ timestamp );
71
+ $ versionId = getenv ('GOOGLE_VERSION_ID ' ) ?: self ::$ mcServiceName ;
60
72
61
- // Declaring Cloud Run services
62
- self ::$ nginxService = new CloudRun (self ::$ projectId , ['service ' => $ versionId ]);
63
- self ::$ phpService = new CloudRun (self ::$ projectId , ['service ' => $ versionId ]);
73
+ self ::$ mcService = new CloudRun (self ::$ projectId , ['service ' => $ versionId ]);
64
74
65
75
// Declaring Cloud Build image tags
66
- self ::$ nginxImage = sprintf ('%s-docker.pkg.dev/%s/%s/nginx ' , $ region , self ::$ projectId , $ repoName );
67
- self ::$ appImage = sprintf ('%s-docker.pkg.dev/%s/%s/php ' , $ region , self ::$ projectId , $ repoName );
76
+ self ::$ nginxImage = sprintf ('%s-docker.pkg.dev/%s/%s/nginx ' , self :: $ region , self ::$ projectId , self :: $ repoName );
77
+ self ::$ appImage = sprintf ('%s-docker.pkg.dev/%s/%s/php ' , self :: $ region , self ::$ projectId , self :: $ repoName );
68
78
}
69
79
70
80
private static function beforeDeploy ()
71
81
{
72
82
self ::setUpDeploymentVars ();
83
+ self ::buildImages ();
84
+ self ::doYamlSubstitution ();
73
85
74
86
// Suppress gcloud prompts during deployment.
75
87
putenv ('CLOUDSDK_CORE_DISABLE_PROMPTS=1 ' );
76
88
}
77
89
78
90
/**
79
- * Deploy the Cloud Run services (nginx, php app)
91
+ * Build nginx + hello php container images
80
92
*/
81
- private static function doDeploy ()
93
+ private static function buildImages ()
82
94
{
83
- // Build & deploy nginx container image
84
- if (false === self ::$ nginxService ->build (self ::$ nginxImage , [], '../nginx ' )) {
95
+ if (false === self ::$ mcService ->build (self ::$ nginxImage , [], './nginx ' )) {
85
96
return false ;
86
97
}
87
- if (false === self ::$ nginxService -> deploy (self ::$ nginxImage )) {
98
+ if (false === self ::$ mcService -> build (self ::$ appImage , [], ' ./php-app ' )) {
88
99
return false ;
89
100
}
101
+ }
90
102
91
- // Build & deploy php app container image
92
- if ( false === self :: $ phpService -> build ( self :: $ appImage , [], ' ../php-app ' )) {
93
- return false ;
94
- }
95
- if ( false === self :: $ phpService -> deploy ( self :: $ appImage )) {
96
- return false ;
97
- }
103
+ /**
104
+ * Execute yaml substitution
105
+ */
106
+ private static function doYamlSubstitution ()
107
+ {
108
+ // Execute yaml substitution
109
+ $ subCmd = sprintf ( ' sed -i -e s/MC_SERVICE_NAME/%s/g -e s/REGION/%s/g -e s/REPO_NAME/%s/g -e s/PROJECT_ID/%s/g service.yaml ' , self :: $ mcServiceName , self :: $ region , self :: $ repoName , self :: $ projectId );
98
110
99
- return true ;
111
+ return self :: execCmd ( $ subCmd ) ;
100
112
}
101
113
102
114
/**
103
- * Delete a deployed Cloud Run service.
115
+ * Deploy the Cloud Run services (nginx, php app)
104
116
*/
105
- private static function doDelete ()
117
+ private static function doDeploy ()
106
118
{
107
- // Delete nginx Cloud Run service
108
- self ::$ nginxService ->delete ();
109
- self ::$ nginxService ->deleteImage (self ::$ nginxImage );
119
+ // Execute multi-container service deployment
120
+ $ mcCmd = sprintf ('gcloud run services replace service.yaml --region %s --quiet ' , self ::$ region );
110
121
111
- // Delete hello php Cloud Run service
112
- self ::$ phpService ->delete ();
113
- self ::$ phpService ->deleteImage (self ::$ appImage );
122
+ return self ::execCmd ($ mcCmd );
114
123
}
115
124
125
+ /**
126
+ * Delete a deployed Cloud Run MC service and related images.
127
+ */
128
+ private static function doDelete ()
129
+ {
130
+ self ::$ mcService ->delete ();
131
+ self ::$ mcService ->deleteImage (self ::$ nginxImage );
132
+ self ::$ mcService ->deleteImage (self ::$ appImage );
133
+ }
134
+
135
+ /**
136
+ * Test that the multi-container is running with both
137
+ * serving and sidecar running as expected
138
+ */
116
139
public function testService ()
117
140
{
118
- $ targetAudience = self ::getBaseUri ();
119
-
120
- // create middleware
121
- $ middleware = ApplicationDefaultCredentials::getIdTokenMiddleware ($ targetAudience );
122
- $ stack = HandlerStack::create ();
123
- $ stack ->push ($ middleware );
124
-
125
- // create the HTTP client
126
- $ client = new Client ([
127
- 'handler ' => $ stack ,
128
- 'auth ' => 'google_auth ' ,
129
- 'base_uri ' => $ targetAudience ,
130
- ]);
131
-
132
- // Run the test.
133
- $ resp = $ client ->get ('/ ' );
134
- $ this ->assertEquals ('200 ' , $ resp ->getStatusCode ());
135
- $ this ->assertEquals ('Hello World! ' , (string ) $ resp ->getBody ());
141
+ $ mcUrl = self ::execCmd (sprintf ('gcloud run services describe %s --region %s --format "value(status.url)" ' , self ::$ mcServiceName , self ::$ region ));
142
+ $ mcStatus = self ::execCmd (sprintf ('gcloud run services describe %s --region %s --format "value(status.conditions[0].type)" ' , self ::$ mcServiceName , self ::$ region ));
143
+
144
+ echo "=====url===== " ;
145
+ echo "$ {mcUrl}" ;
146
+ echo "$ {mcStatus}" ;
147
+ echo "========== " ;
148
+
149
+ if (empty ($ mcUrl ) or empty ($ mcStatus )) {
150
+ return false ;
151
+ }
152
+
153
+ # Checking that fpm (FastCGI Process Manager)
154
+ $ mcNginxLog = exec ('gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=%s AND labels.container_name=nginx" | grep -e "Default STARTUP TCP probe succeeded after 1 attempt for container nginx" ' , self ::$ mcServiceName );
155
+ # Check Cloud Run MC nginx & hellophp logs for signs of successful deployment and connection
156
+ $ mcHelloPHPLog = exec ('gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=%s AND labels.container_name=hellophp" | grep -e "NOTICE: fpm is running, pid 1" ' , self ::$ mcServiceName );
157
+
158
+ echo "=====log===== " ;
159
+ echo "$ {mcNginxLog}" ;
160
+ echo "$ {mcHelloPHPLog}" ;
161
+ echo "========== " ;
162
+
163
+ // Validate that the expected logs have been recovered
164
+ if (empty ($ mcNginxLog ) or empty ($ mcHelloPHPLog )) {
165
+ return false ;
166
+ }
167
+
168
+ return true ;
136
169
}
137
170
138
171
public function getBaseUri ()
139
172
{
140
- return self ::$ phpService ->getBaseUrl ();
173
+ return self ::$ mcService ->getBaseUrl ();
141
174
}
142
175
}
0 commit comments