1313use OpenTelemetry \SDK \Resource \ResourceInfoFactory ;
1414use OpenTelemetry \SemConv \ResourceAttributes ;
1515use OpenTelemetry \SemConv \ResourceAttributeValues ;
16+ use org \bovigo \vfs \vfsStream ;
17+ use org \bovigo \vfs \vfsStreamDirectory ;
1618use PHPUnit \Framework \Attributes \CoversClass ;
1719use PHPUnit \Framework \TestCase ;
1820use Psr \Http \Message \RequestInterface ;
1921use Zalas \PHPUnit \Globals \Attribute \Server ;
2022
21- function file_get_contents (string $ filename )
22- {
23- if (($ _SERVER ['FAIL_IO ' ] ?? 'false ' ) === 'true ' ) {
24- return false ;
25- }
26- if (str_starts_with ($ filename , '/sys/devices/virtual/dmi/id ' )) {
27- return match (substr ($ filename , 28 )) {
28- 'sys_vendor ' => (($ _SERVER ['WRONG_VENDOR ' ] ?? 'false ' ) === 'true ' ) ? 'AWS ' : 'DigitalOcean ' ,
29- 'product_family ' => 'DigitalOcean_Droplet ' ,
30- 'board_asset_tag ' => '10000000 ' ,
31- default => 'unknown '
32- };
33- }
34-
35- return \file_get_contents ($ filename );
36- }
37-
3823function gethostname ()
3924{
4025 return 'test-server ' ;
@@ -44,21 +29,37 @@ function gethostname()
4429class DigitalOceanDetectorTest extends TestCase
4530{
4631 private mixed $ errorLog ;
32+ private vfsStreamDirectory $ vfs ;
4733
4834 public function setUp (): void
4935 {
36+ /** mock sysfs with DigitalOcean SMBIOS pointers */
37+ $ this ->vfs = vfsStream::setup ('/ ' , structure: [
38+ 'sys ' => [
39+ 'devices ' => [
40+ 'virtual ' => [
41+ 'dmi ' => [
42+ 'id ' => [
43+ 'board_asset_tag ' => '10000000 ' ,
44+ 'product_family ' => 'DigitalOcean_Droplet ' ,
45+ 'sys_vendor ' => 'DigitalOcean ' ,
46+ ],
47+ ],
48+ ],
49+ ],
50+ ],
51+ ]);
52+
53+ /** mock stdout for `error_log` */
5054 $ this ->errorLog = tmpfile ();
5155 /** @psalm-suppress PossiblyFalseArgument */
5256 ini_set ('error_log ' , stream_get_meta_data ($ this ->errorLog )['uri ' ]);
5357
58+ /** mock HTTP client and DigitalOcean API responses */
5459 $ responseFactory = MessageFactoryResolver::create ()->resolveResponseFactory ();
5560 $ client = $ this ->createStub (Psr18Client::class);
5661 $ client ->method ('sendRequest ' )->willReturnCallback (function (RequestInterface $ request ) use ($ responseFactory ) {
5762 if ((string ) $ request ->getUri () === 'http://169.254.169.254/metadata/v1.json ' ) {
58- if (($ _SERVER ['FAIL_METADATA ' ] ?? 'false ' ) === 'true ' ) {
59- return $ responseFactory ->createResponse (500 );
60- }
61-
6263 /** @psalm-suppress PossiblyFalseArgument */
6364 return $ responseFactory ->createResponse ()->withBody (
6465 Stream::create (file_get_contents (dirname (__FILE__ ) . DIRECTORY_SEPARATOR . 'mock-metadata.json ' ))
@@ -102,7 +103,7 @@ public function test_droplet_attributes_with_no_authz()
102103 ResourceAttributes::HOST_NAME => 'test-server ' ,
103104 ResourceAttributes::OS_TYPE => ResourceAttributeValues::OS_TYPE_LINUX ,
104105 ]),
105- (new DigitalOceanDetector ())->getResource ()->getAttributes ()
106+ (new DigitalOceanDetector ($ this -> vfs -> url () ))->getResource ()->getAttributes ()
106107 );
107108 }
108109
@@ -121,7 +122,7 @@ public function test_droplet_attributes_with_account_only_authz()
121122 ResourceAttributes::HOST_NAME => 'test-server ' ,
122123 ResourceAttributes::OS_TYPE => ResourceAttributeValues::OS_TYPE_LINUX ,
123124 ]),
124- (new DigitalOceanDetector ())->getResource ()->getAttributes ()
125+ (new DigitalOceanDetector ($ this -> vfs -> url () ))->getResource ()->getAttributes ()
125126 );
126127 /** @psalm-suppress PossiblyFalseArgument */
127128 $ this ->assertStringContainsString (
@@ -148,7 +149,7 @@ public function test_droplet_attributes_with_droplet_only_authz()
148149 ResourceAttributes::HOST_TYPE => 's-1vcpu-1gb ' ,
149150 ResourceAttributes::OS_NAME => 'Debian ' ,
150151 ]),
151- (new DigitalOceanDetector ())->getResource ()->getAttributes ()
152+ (new DigitalOceanDetector ($ this -> vfs -> url () ))->getResource ()->getAttributes ()
152153 );
153154 /** @psalm-suppress PossiblyFalseArgument */
154155 $ this ->assertStringContainsString (
@@ -157,12 +158,23 @@ public function test_droplet_attributes_with_droplet_only_authz()
157158 );
158159 }
159160
160- #[Server('FAIL_METADATA ' , 'true ' )]
161161 public function test_no_droplet_attributes ()
162162 {
163+ /** mock HTTP client and with failing response */
164+ $ client = $ this ->createStub (Psr18Client::class);
165+ $ client ->method ('sendRequest ' )->willReturnCallback (function () {
166+ $ responseFactory = MessageFactoryResolver::create ()->resolveResponseFactory ();
167+
168+ return $ responseFactory ->createResponse (500 );
169+ });
170+ $ clientDiscoverer = $ this ->createStub (DiscoveryInterface::class);
171+ $ clientDiscoverer ->method ('available ' )->willReturn (true );
172+ $ clientDiscoverer ->method ('create ' )->willReturn ($ client );
173+ Discovery::setDiscoverers ([$ clientDiscoverer ]);
174+
163175 $ this ->assertEquals (
164176 ResourceInfoFactory::emptyResource (),
165- (new DigitalOceanDetector ())->getResource ()
177+ (new DigitalOceanDetector ($ this -> vfs -> url () ))->getResource ()
166178 );
167179 /** @psalm-suppress PossiblyFalseArgument */
168180 $ this ->assertStringContainsString (
@@ -171,12 +183,16 @@ public function test_no_droplet_attributes()
171183 );
172184 }
173185
174- #[Server('WRONG_VENDOR ' , 'true ' )]
175186 public function test_not_digitalocean_environment ()
176187 {
188+ /** mock sysfs with AWS SMBIOS pointers */
189+ $ vfs = vfsStream::setup ('/ ' , structure: ['sys ' => ['devices ' => ['virtual ' => ['dmi ' => ['id ' => [
190+ 'sys_vendor ' => 'AWS ' ,
191+ ]]]]]]);
192+
177193 $ this ->assertEquals (
178194 ResourceInfoFactory::emptyResource (),
179- (new DigitalOceanDetector ())->getResource ()
195+ (new DigitalOceanDetector ($ vfs -> url () ))->getResource ()
180196 );
181197 /** @psalm-suppress PossiblyFalseArgument */
182198 $ this ->assertStringContainsString (
@@ -185,12 +201,14 @@ public function test_not_digitalocean_environment()
185201 );
186202 }
187203
188- #[Server('FAIL_IO ' , 'true ' )]
189204 public function test_not_linux ()
190205 {
206+ /** mock sysfs with no SMBIOS pointers */
207+ $ vfs = vfsStream::setup ('/ ' );
208+
191209 $ this ->assertEquals (
192210 ResourceInfoFactory::emptyResource (),
193- (new DigitalOceanDetector ())->getResource ()
211+ (new DigitalOceanDetector ($ vfs -> url () ))->getResource ()
194212 );
195213 /** @psalm-suppress PossiblyFalseArgument */
196214 $ this ->assertStringContainsString (
0 commit comments