assertInstanceOf( PartitionInterface::class, new Partition($definition) ); } /** * @dataProvider invalidPartitionDefinitionProvider * * @param array $invalidDefinition */ public function testRejectsInvalidDefinitions(array $invalidDefinition) { $this->expectExceptionMessageMatches("/missing required \w+ field/"); $this->expectException(\InvalidArgumentException::class); new Partition($invalidDefinition); } /** * @dataProvider partitionDefinitionProvider * * @param array $definition */ public function testReportsData(array $definition) { $this->assertSame( $definition['partition'], (new Partition($definition))->getName() ); $this->assertSame( $definition['dnsSuffix'], (new Partition($definition))->getDnsSuffix() ); } /** * @dataProvider partitionDefinitionProvider * * @param array $definition */ public function testFipsEndpoint(array $definition) { $partition = new Partition($definition); $resolved = $partition(['region' => 'fips-aws-global', 'service' => 'service']); self::assertStringContainsString('service-fips.amazonaws.com', $resolved['endpoint']); } public function partitionDefinitionProvider() { return [ [[ 'partition' => 'aws_test', 'dnsSuffix' => 'amazonaws.com', 'regions' => [ 'region' => [ 'description' => 'A description', ], ], 'services' => [ 'service' => [ 'endpoints' => [ 'us-east-1' => [], 'us-west-2' => [], 'fips-aws-global' => ['hostname' => 'service-fips.amazonaws.com'], ], ], ], ]], ]; } public function invalidPartitionDefinitionProvider() { $validDefinition = $this->partitionDefinitionProvider()[0][0]; $return = []; foreach ($validDefinition as $requiredKey => $v) { $def = $validDefinition; unset($def[$requiredKey]); $return []= [$def]; } return $return; } /** * @dataProvider partitionDefinitionProvider * * @param array $definition */ public function testReportsRegionMatches(array $definition) { $partition = new Partition($definition); $this->assertTrue($partition->isRegionMatch('region', 'service')); $this->assertFalse($partition->isRegionMatch('foo', 'bar')); } /** * @dataProvider partitionDefinitionProvider * * @param array $definition */ public function testReportsRegionMatchesByPattern(array $definition) { $definition['regionRegex'] = '^fo[\w]{1}'; $partition = new Partition($definition); $this->assertTrue($partition->isRegionMatch('foo', 's3')); $this->assertTrue($partition->isRegionMatch('fou', 's3')); $this->assertFalse($partition->isRegionMatch('bar', 's3')); } /** * @dataProvider serviceRegionsProvider * * @param Partition $partition * @param string $service * @param array $regions * @param bool $allowNonRegionalEndpoints */ public function testEnumeratesRegionsForGivenService( Partition $partition, $service, array $regions, $allowNonRegionalEndpoints ) { $this->assertSame($regions, $partition->getAvailableEndpoints( $service, $allowNonRegionalEndpoints )); } public function serviceRegionsProvider() { $partition = new Partition([ 'partition' => 'foo', 'dnsSuffix' => 'bar', 'regions' => [ 'foo-global' => [], 'buzz' => [], 'pop' => [], ], 'services' => [ 'baz' => [ 'isRegionalized' => false, 'partitionEndpoint' => 'foo-global', 'endpoints' => [ 'foo-global' => [ 'credentialScope' => ['region' => 'quux'] ], ], ], 'fizz' => [ 'endpoints' => [ 'buzz' => [], 'pop' => [], 'pop-external-1-fips' => [], ], ], ], ]); return [ [$partition, 'baz', ['foo-global'], false], [$partition, 'fizz', ['buzz', 'pop'], false], [$partition, 'fizz', ['buzz', 'pop', 'pop-external-1-fips'], true], [$partition, 'quux', [], true], ]; } /** * @dataProvider signingRegionProvider * * @param Partition $partition * @param $region * @param $service * @param $signingRegion */ public function testDeterminesSigningRegion( Partition $partition, $region, $service, $signingRegion ) { $resolved = $partition([ 'scheme' => 'https', 'service' => $service, 'region' => $region, ]); $this->assertArrayHasKey('signingRegion', $resolved); $this->assertSame($signingRegion, $resolved['signingRegion']); } public function signingRegionProvider() { $partition = new Partition([ 'partition' => 'foo', 'dnsSuffix' => 'bar', 'regions' => [], 'services' => [ 'baz' => [ 'isRegionalized' => false, 'partitionEndpoint' => 'foo-global', 'endpoints' => [ 'foo-global' => [ 'credentialScope' => ['region' => 'quux'] ], ], ], 'fizz' => [ 'endpoints' => [ 'buzz' => [], ], ], ], ]); return [ [$partition, 'eu-central-1', 'baz', 'quux'], [$partition, 'eu-central-1', 'fizz', 'eu-central-1'], [$partition, 'us-east-1', 'iot', 'us-east-1'], ]; } /** * @dataProvider endpointProvider * * @param Partition $partition * @param $region * @param $service * @param $endpoint */ public function testDeterminesEndpoint( Partition $partition, $region, $service, $endpoint ) { $resolved = $partition([ 'scheme' => 'https', 'service' => $service, 'region' => $region, ]); $this->assertArrayHasKey('endpoint', $resolved); $this->assertSame($endpoint, $resolved['endpoint']); } public function endpointProvider() { $partition = new Partition([ 'partition' => 'foo', 'dnsSuffix' => 'bar', 'defaults' => ['hostname' => '{service}.{region}.{dnsSuffix}'], 'regions' => [], 'services' => [ 'baz' => [ 'isRegionalized' => false, 'partitionEndpoint' => 'foo-global', 'endpoints' => [ 'foo-global' => ['hostname' => 'quux'], ], ], 'fizz' => [ 'endpoints' => [ 'buzz' => [], 'pop' => [ 'hostname' => '{region}.{service}.{dnsSuffix}', ], ], ], ], ]); return [ [$partition, 'us-east-1', 'baz', 'https://quux'], [$partition, 'buzz', 'fizz', 'https://fizz.buzz.bar'], [$partition, 'pop', 'fizz', 'https://pop.fizz.bar'], [$partition, 'us-east-1', 'iot', 'https://iot.us-east-1.bar'], ]; } public function testIgnoresIsRegionalizedFlagIfPartitionEndpointAbsent() { $partition = new Partition([ 'partition' => 'foo', 'dnsSuffix' => 'bar', 'defaults' => ['hostname' => '{service}.{region}.{dnsSuffix}'], 'regions' => [], 'services' => [ 'baz' => [ 'isRegionalized' => false, 'endpoints' => [ 'foo-global' => ['hostname' => 'quux'], ], ], ], ]); $resolved = $partition([ 'service' => 'baz', 'region' => 'us-east-1', 'scheme' => 'https', ]); $this->assertArrayHasKey('endpoint', $resolved); $this->assertSame('https://baz.us-east-1.bar', $resolved['endpoint']); } /** * @dataProvider signatureVersionProvider * * @param Partition $partition * @param $region * @param $service * @param $signatureVersion */ public function testDeterminesSignatureVersion( Partition $partition, $region, $service, $signatureVersion ) { $resolved = $partition([ 'scheme' => 'https', 'service' => $service, 'region' => $region, ]); $this->assertArrayHasKey('signatureVersion', $resolved); $this->assertSame($signatureVersion, $resolved['signatureVersion']); } public function signatureVersionProvider() { $partition = new Partition([ 'partition' => 'foo', 'dnsSuffix' => 'bar', 'defaults' => ['signatureVersions' => ['v4']], 'regions' => [], 'services' => [ 'baz' => [ 'isRegionalized' => false, 'partitionEndpoint' => 'foo-global', 'endpoints' => [ 'foo-global' => ['signatureVersions' => ['s3v4']], ], ], 'fizz' => [ 'defaults' => ['signatureVersions' => ['anonymous']], 'endpoints' => [ 'buzz' => [], 'pop' => [ 'signatureVersions' => ['s3v4'], ], ], ], 'quux' => [ 'endpoints' => [ 'puff' => [], ], ], 'sdb' => [ 'defaults' => ['signatureVersions' => ['v2']], 'endpoints' => [ 'us-east-1' => [], ] ] ], ]); return [ // partition endpoint setting [$partition, 'us-east-1', 'baz', 's3v4'], // service setting [$partition, 'buzz', 'fizz', 'anonymous'], // service endpoint setting [$partition, 'pop', 'fizz', 's3v4'], // no overrides [$partition, 'puff', 'quux', 'v4'], // unknown region [$partition, 'us-east-1', 'quux', 'v4'], // unknown service [$partition, 'us-east-1', 'iot', 'v4'], // sdb [$partition, 'us-east-1', 'sdb', null] ]; } /** * @dataProvider signingNameProvider * * @param Partition $partition * @param string $region * @param string $service * @param string $signingName */ public function testDeterminesSigningName( Partition $partition, $region, $service, $signingName ) { $resolved = $partition([ 'scheme' => 'https', 'service' => $service, 'region' => $region, ]); $this->assertArrayHasKey('signingName', $resolved); $this->assertSame($signingName, $resolved['signingName']); } public function signingNameProvider() { $partition = new Partition([ 'partition' => 'foo', 'dnsSuffix' => 'bar', 'regions' => [], 'services' => [ 'baz' => [ 'isRegionalized' => false, 'partitionEndpoint' => 'foo-global', 'endpoints' => [ 'foo-global' => [ 'credentialScope' => ['service' => 'quux'] ], ], ], 'fizz' => [ 'defaults' => [ 'credentialScope' => ['service' => 'execute-api'], ], 'endpoints' => [ 'buzz' => [ 'credentialScope' => ['service' => 'pop'], ], ], ], 'quux' => [ 'endpoints' => [ 'puff' => [], ], ], ], ]); return [ // partition endpoint setting [$partition, 'eu-central-1', 'baz', 'quux'], // service setting [$partition, 'eu-central-1', 'fizz', 'execute-api'], // service endpoint setting [$partition, 'buzz', 'fizz', 'pop'], // no overrides [$partition, 'puff', 'quux', 'quux'], // unknown service [$partition, 'us-east-2', 's3', 's3'], ]; } /** * @dataProvider stsEndpointTestCases * * @param $region * @param $configOption * @param $expectedEndpoint */ public function testResolvesStsRegionalEndpoints( $region, $configOption, $expectedEndpoint ) { $data = json_decode( file_get_contents(__DIR__ . '/fixtures/sts_regional_endpoints.json'), true ); $partition = new Partition($data['partitions'][0]); $params = [ 'service' => 'sts', 'region' => $region ]; if (!empty($configOption)) { $params['options'] = [ 'sts_regional_endpoints' => $configOption ]; } $data = $partition($params); $this->assertEquals($expectedEndpoint, $data['endpoint']); } public function stsEndpointTestCases() { return [ [ 'us-west-2', 'legacy', 'https://sts.amazonaws.com' ], [ 'us-west-2', 'regional', 'https://sts.us-west-2.amazonaws.com' ], [ 'us-west-2', null, 'https://sts.amazonaws.com' ], [ 'us-west-2-fips', 'legacy', 'https://sts-fips.us-west-2.amazonaws.com' ], [ 'us-west-2-fips', 'regional', 'https://sts-fips.us-west-2.amazonaws.com' ], [ 'us-west-2-fips', null, 'https://sts-fips.us-west-2.amazonaws.com' ], [ 'ap-east-1', 'legacy', 'https://sts.ap-east-1.amazonaws.com' ], [ 'ap-east-1', 'regional', 'https://sts.ap-east-1.amazonaws.com' ], [ 'ap-east-1', null, 'https://sts.ap-east-1.amazonaws.com' ], [ 'aws-global', 'legacy', 'https://sts.amazonaws.com' ], [ 'aws-global', 'regional', 'https://sts.amazonaws.com' ], [ 'aws-global', null, 'https://sts.amazonaws.com' ], ]; } /** * @dataProvider s3EndpointTestCases * * @param $region * @param $configOption * @param $expectedEndpoint */ public function testResolvesS3RegionalEndpoint( $region, $configOption, $expectedEndpoint ) { $data = json_decode( file_get_contents(__DIR__ . '/fixtures/s3_us_east_1_regional_endpoint.json'), true ); $partition = new Partition($data['partitions'][0]); $params = [ 'service' => 's3', 'region' => $region ]; if (!empty($configOption)) { $params['options'] = [ 's3_us_east_1_regional_endpoint' => $configOption ]; } $data = $partition($params); $this->assertEquals($expectedEndpoint, $data['endpoint']); } public function s3EndpointTestCases() { return [ [ 'us-west-2', 'legacy', 'https://s3.us-west-2.amazonaws.com' ], [ 'us-west-2', 'regional', 'https://s3.us-west-2.amazonaws.com' ], [ 'us-west-2', null, 'https://s3.us-west-2.amazonaws.com' ], [ 'us-east-1', 'legacy', 'https://s3.amazonaws.com' ], [ 'us-east-1', 'regional', 'https://s3.us-east-1.amazonaws.com' ], [ 'us-east-1', null, 'https://s3.amazonaws.com' ], [ 'aws-global', 'legacy', 'https://s3.amazonaws.com' ], [ 'aws-global', 'regional', 'https://s3.amazonaws.com' ], [ 'aws-global', null, 'https://s3.amazonaws.com' ], ]; } /** * @dataProvider variantTagProvider * * @param array $definition * @param @fipsConfig * @param @dualstackConfig */ public function testGetVariantIgnoresVariantTagOrder( array $definition, $fipsConfig, $dualstackConfig ) { $partition = new Partition($definition); $resolved = $partition([ 'region' => 'us-east-1', 'service' => 'service', 'options' => [ 'use_fips_endpoint' => $fipsConfig, 'use_dual_stack_endpoint' => $dualstackConfig ] ]); $this->assertStringContainsString('testsuffix.com', $resolved['endpoint']); } public function variantTagProvider() { $useFipsEndpointConfig = $this->getMockBuilder(UseFipsEndpoint\Configuration::class) ->disableOriginalConstructor() ->getMock(); $useFipsEndpointConfig->expects($this->any()) ->method('isUseFipsEndpoint') ->willReturn(true); $useDualstackEndpointConfig = $this->getMockBuilder(UseDualstackEndpoint\Configuration::class) ->disableOriginalConstructor() ->getMock(); $useDualstackEndpointConfig->expects($this->any()) ->method('isUseDualstackEndpoint') ->willReturn(true); return [ [ [ 'partition' => 'aws_test', 'dnsSuffix' => 'amazonaws.com', 'regions' => [ 'region' => [ 'description' => 'A description', ], ], 'services' => [ 'service' => [ 'endpoints' => [ 'us-east-1' => [ 'variants' => [[ 'hostname' => 'service-fips.dualstack.testsuffix.com', 'tags' => ['fips', 'dualstack'] ]] ], 'us-west-2' => [], ], ], ], ], $useFipsEndpointConfig, $useDualstackEndpointConfig ], [ [ 'partition' => 'aws_test', 'dnsSuffix' => 'amazonaws.com', 'regions' => [ 'region' => [ 'description' => 'A description', ], ], 'services' => [ 'service' => [ 'endpoints' => [ 'us-east-1' => [ 'variants' => [[ 'hostname' => 'service-fips.dualstack.testsuffix.com', 'tags' => ['dualstack', 'fips'] ]] ], 'us-west-2' => [], ], ], ], ], $useFipsEndpointConfig, $useDualstackEndpointConfig ], [ [ 'partition' => 'aws_test', 'dnsSuffix' => 'amazonaws.com', 'regions' => [ 'region' => [ 'description' => 'A description', ], ], 'services' => [ 'service' => [ 'endpoints' => [ 'us-east-1' => [ 'variants' => [[ 'hostname' => 'service-fips.dualstack.testsuffix.com', 'tags' => ['fips'] ]] ], 'us-west-2' => [], ], ], ], ], $useFipsEndpointConfig, null ], [ [ 'partition' => 'aws_test', 'dnsSuffix' => 'amazonaws.com', 'regions' => [ 'region' => [ 'description' => 'A description', ], ], 'services' => [ 'service' => [ 'endpoints' => [ 'us-east-1' => [ 'variants' => [[ 'hostname' => 'service-fips.dualstack.testsuffix.com', 'tags' => ['dualstack'] ]] ], 'us-west-2' => [], ], ], ], ], null, $useDualstackEndpointConfig ] ]; } /** * @dataProvider variantTagEmptyProvider * * @param array $definition * @param @fipsConfig * @param @dualstackConfig */ public function testGetVariantNoVariantSelectedIfTagsAreEmpty( array $definition, $fipsConfig, $dualstackConfig ) { $partition = new Partition($definition); $resolved = $partition([ 'region' => 'us-east-1', 'service' => 'service', 'options' => [ 'use_fips_endpoint' => $fipsConfig, 'use_dual_stack_endpoint' => $dualstackConfig ] ]); $this->assertStringNotContainsString('testsuffix.com', $resolved['endpoint']); } public function variantTagEmptyProvider() { $useFipsEndpointConfig = $this->getMockBuilder(UseFipsEndpoint\Configuration::class) ->disableOriginalConstructor() ->getMock(); $useFipsEndpointConfig->expects($this->any()) ->method('isUseFipsEndpoint') ->willReturn(true); $useDualstackEndpointConfig = $this->getMockBuilder(UseDualstackEndpoint\Configuration::class) ->disableOriginalConstructor() ->getMock(); $useDualstackEndpointConfig->expects($this->any()) ->method('isUseDualstackEndpoint') ->willReturn(true); return [ [ [ 'partition' => 'aws_test', 'dnsSuffix' => 'amazonaws.com', 'regions' => [ 'region' => [ 'description' => 'A description', ], ], 'services' => [ 'service' => [ 'endpoints' => [ 'us-east-1' => [ 'variants' => [[ 'hostname' => 'service-fips.dualstack.testsuffix.com', 'tags' => [] ]] ], 'us-west-2' => [], ], ], ], ], $useFipsEndpointConfig, $useDualstackEndpointConfig ], [ [ 'partition' => 'aws_test', 'dnsSuffix' => 'amazonaws.com', 'regions' => [ 'region' => [ 'description' => 'A description', ], ], 'services' => [ 'service' => [ 'endpoints' => [ 'us-east-1' => [ 'variants' => [[ 'hostname' => 'service-fips.dualstack.testsuffix.com', 'tags' => [] ]] ], 'us-west-2' => [], ], ], ], ], $useFipsEndpointConfig, null ], [ [ 'partition' => 'aws_test', 'dnsSuffix' => 'amazonaws.com', 'regions' => [ 'region' => [ 'description' => 'A description', ], ], 'services' => [ 'service' => [ 'endpoints' => [ 'us-east-1' => [ 'variants' => [[ 'hostname' => 'service-fips.dualstack.testsuffix.com', 'tags' => [] ]] ], 'us-west-2' => [], ], ], ], ], null, $useDualstackEndpointConfig ], [ [ 'partition' => 'aws_test', 'dnsSuffix' => 'amazonaws.com', 'regions' => [ 'region' => [ 'description' => 'A description', ], ], 'services' => [ 'service' => [ 'endpoints' => [ 'us-east-1' => [ 'variants' => [[ 'hostname' => 'service-fips.dualstack.testsuffix.com', 'tags' => [] ]] ], 'us-west-2' => [], ], ], ], ], null, null ] ]; } /** * @dataProvider booleanConfigProvider * * @param array $tags * @param @fipsConfig * @param @dualstackConfig */ public function testGetVariantWithBooleanConfigValues( array $tags, $fipsConfig, $dualstackConfig ) { $definition = [ 'partition' => 'aws_test', 'dnsSuffix' => 'amazonaws.com', 'regions' => [ 'region' => [ 'description' => 'A description', ], ], 'services' => [ 'service' => [ 'endpoints' => [ 'us-east-1' => [ 'variants' => [[ 'hostname' => 'service-fips.dualstack.testsuffix.com', 'tags' => $tags ]] ], 'us-west-2' => [], ], ], ], ]; $partition = new Partition($definition); $resolved = $partition([ 'region' => 'us-east-1', 'service' => 'service', 'options' => [ 'use_fips_endpoint' => $fipsConfig, 'use_dual_stack_endpoint' => $dualstackConfig ] ]); $this->assertStringContainsString('testsuffix.com', $resolved['endpoint']); } public function booleanConfigProvider() { return [ [ ['fips'], true, false ], [ ['dualstack'], false, true ], [ ['fips', 'dualstack'], true, true ] ]; } }