Loading modules/cloud_service_providers/openstack/src/Form/OpenStackPortEditForm.php +1 −1 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ class OpenStackPortEditForm extends AwsCloudContentForm { protected $openStackOperationsService; /** * OpenStackPortCreateForm constructor. * OpenStackPortEditForm constructor. * * @param \Drupal\aws_cloud\Service\AwsCloud\AwsCloudOperationsServiceInterface $aws_cloud_operations_service * The AWS Cloud Operations service. Loading modules/cloud_service_providers/openstack/src/Service/Rest/OpenStackServiceMock.php +39 −0 Original line number Diff line number Diff line Loading @@ -718,6 +718,45 @@ class OpenStackServiceMock extends OpenStackService { return $this->getMockData(__FUNCTION__); } /** * Create an OpenStack port. * * @param array $params * Parameters to pass to the API. * * @return array * The port create API response. */ public function createPort(array $params = []): array { return $this->getMockData(__FUNCTION__); } /** * Update an OpenStack port. * * @param array $params * Parameters to pass to the API. * * @return array * The port update API response. */ public function updatePort(array $params = []): array { return $this->getMockData(__FUNCTION__); } /** * Delete an OpenStack port. * * @param array $params * Parameters to pass to the API. * * @return array * The port delete API response. */ public function deletePort(array $params = []): array { return $this->getMockData(__FUNCTION__); } /** * Get routers. * Loading modules/cloud_service_providers/openstack/tests/src/Functional/OpenStack/OpenStackPortTest.php 0 → 100644 +440 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\openstack\Functional\OpenStack; use Drupal\openstack\Entity\OpenStackNetwork; use Drupal\openstack\Entity\OpenStackPort; use Drupal\openstack\Entity\OpenStackSubnet; use Drupal\Tests\openstack\Functional\OpenStackTestBase; /** * Tests OpenStack port. * * @group OpenStack */ class OpenStackPortTest extends OpenStackTestBase { public const OPENSTACK_PORT_REPEAT_COUNT = 2; /** * {@inheritdoc} */ protected function getPermissions(): array { return [ 'view all cloud service providers', 'list openstack port', 'add openstack port', 'view any openstack port', 'edit any openstack port', 'delete any openstack port', ]; } /** * {@inheritdoc} * * @throws \Exception */ protected function getMockDataTemplateVars(): array { return [ 'port_id' => 'port-' . $this->getRandomId(), 'network_id' => 'network-' . $this->getRandomId(), 'project_id' => $this->cloudConfig->get('field_project_id')->value, 'create_time' => date('c'), ]; } /** * Tests CRUD for port information. * * @throws \Behat\Mink\Exception\ExpectationException * @throws \Exception */ public function testPort(): void { $cloud_context = $this->cloudContext; // List port for OpenStack. $this->drupalGet("/clouds/openstack/$cloud_context/port"); $this->assertNoErrorMessage(); // Create random networks. $networks = $this->createNetworksRandomTestFormData(); $this->updateDescribeNetworksMockData($networks); // Create the network entities. $i = 1; foreach ($networks ?: [] as $network) { $this->createNetworkTestEntity(OpenStackNetwork::class, $i++, $cloud_context, $network['Name'], $network['NetworkId']); // Create random subnets. $subnets = $this->createopenstackSubnetsRandomTestFormData(); $this->updateDescribeSubnetsMockData($subnets); $subnet_index = 1; foreach ($subnets ?: [] as $subnet) { $this->createOpenStackSubnetTestEntity(OpenStackSubnet::class, $subnet_index++, $cloud_context, $subnet['Name'], $subnet['SubnetId'], $network['NetworkId']); $subnet_index++; } $i++; } // Add a new port. $add = $this->createPortTestFormData(self::OPENSTACK_PORT_REPEAT_COUNT); for ($i = 0, $num = 1; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++, $num++) { $this->addPortMockData($add[$i], $cloud_context, $this->webUser->id()); // Set network ID. $add[$i]['network_id'] = $networks[array_rand($networks)]['NetworkId']; // Set subnet ID. $add[$i]['subnet'] = $subnets[array_rand($subnets)]['SubnetId']; $this->drupalGet("/clouds/openstack/$cloud_context/port/add"); $this->submitForm( $add[$i], $this->t('Save')); $this->assertNoErrorMessage(); $t_args = ['@type' => 'Port', '%label' => $add[$i]['name']]; $this->assertSession()->pageTextContains(strip_tags($this->t('The @type %label has been created.', $t_args))); // Make sure View. $this->drupalGet("/clouds/openstack/$cloud_context/port/$num"); $this->assertNoErrorMessage(); // Make sure listing. $this->drupalGet("/clouds/openstack/$cloud_context/port"); $this->assertNoErrorMessage(); for ($j = 0; $j < $num; $j++) { $this->assertSession()->pageTextContains($add[$j]['name']); } // Make sure uid. $this->drupalGet("/clouds/openstack/$cloud_context/port/$num"); $this->assertSession()->pageTextContains($this->webUser->getAccountName()); } for ($i = 0, $num = 1; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++, $num++) { // Make sure the all port listing exists. $this->drupalGet('/clouds/openstack/port'); $this->assertNoErrorMessage(); for ($j = 0; $j < $num; $j++) { $this->assertSession()->pageTextContains($add[$j]['name']); } } // Edit port information. $edit = $this->createPortTestFormData(self::OPENSTACK_PORT_REPEAT_COUNT); for ($i = 0, $num = 1; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++, $num++) { unset( $edit[$i]['network_id'], $edit[$i]['subnet'], $edit[$i]['fixed_ips'], $edit[$i]['device_id'], $edit[$i]['device_owner'], $edit[$i]['ip_address_or_subnet'], ); $this->updatePortMockData($i, $edit[$i]['name']); $this->drupalGet("/clouds/openstack/$cloud_context/port/$num/edit"); $this->submitForm( $edit[$i], $this->t('Save')); $this->assertNoErrorMessage(); $t_args = ['@type' => 'Port', '%label' => $edit[$i]['name']]; $this->assertSession()->pageTextContains(strip_tags($this->t('The @type %label has been updated.', $t_args))); $this->drupalGet("/clouds/openstack/$cloud_context/port"); $this->assertNoErrorMessage(); $this->assertSession()->pageTextContains($edit[$i]['name']); // Make sure listing. $this->drupalGet("/clouds/openstack/$cloud_context/port"); $this->assertNoErrorMessage(); for ($j = 0; $j < $num; $j++) { $this->assertSession()->pageTextContains($edit[$i]['name']); } // Make sure uid. $this->drupalGet("/clouds/openstack/$cloud_context/port/$num"); $this->assertSession()->pageTextContains($this->webUser->getAccountName()); } // Delete port. for ($i = 0, $num = 1; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++, $num++) { $this->drupalGet("/clouds/openstack/$cloud_context/port/$num/delete"); $this->assertNoErrorMessage(); $this->drupalGet("/clouds/openstack/$cloud_context/port/$num/delete"); $this->submitForm( [], $this->t('Delete')); $this->assertNoErrorMessage(); $t_args = ['@type' => 'Port', '@label' => $edit[$i]['name']]; $this->assertSession()->pageTextContains(strip_tags($this->t('The @type @label has been deleted.', $t_args))); // Make sure listing. $this->drupalGet("/clouds/openstack/$cloud_context/port"); $this->assertNoErrorMessage(); } } /** * Tests deleting ports with bulk operation. * * @throws \Exception */ public function testPortBulk(): void { for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { // Create port. $ports = $this->createPortsRandomTestFormData(); $index = 0; $entities = []; foreach ($ports ?: [] as $port) { $entities[] = $this->createPortTestEntity(OpenStackPort::class, $index++, $this->cloudContext, $port['Name']); } // The first parameter type should be 'port' in OpenStack. $this->runTestEntityBulk('port', $entities); } } /** * Test updating port. * * @throws \Behat\Mink\Exception\ExpectationException */ public function testUpdatePortList(): void { $cloud_context = $this->cloudContext; // Add a new port. $add = $this->createPortTestFormData(self::OPENSTACK_PORT_REPEAT_COUNT); for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->reloadMockData(); $this->addPortMockData($add[$i], $cloud_context, $this->webUser->id()); } // Make sure listing. $this->drupalGet("/clouds/openstack/$cloud_context/port"); $this->assertNoErrorMessage(); for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextNotContains($add[$i]['name']); } // Click 'Refresh'. $this->clickLink($this->t('Refresh')); $this->assertSession()->pageTextContains($this->t('Updated ports.')); // Make sure listing. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextContains($add[$i]['name']); } // Make sure detailed and edit view. for ($i = 0, $num = 1; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++, $num++) { // Confirm the detailed view. $this->drupalGet("/clouds/openstack/$cloud_context/port/$num"); $this->assertSession()->linkExists($this->t('Edit')); $this->assertSession()->linkByHrefExists("/clouds/openstack/$cloud_context/port/$num/edit"); $this->assertSession()->linkExists($this->t('Delete')); $this->assertSession()->linkByHrefExists("/clouds/openstack/$cloud_context/port/$num/delete"); $this->assertSession()->linkExists($this->t('List OpenStack ports')); // Make sure uid. $this->assertSession()->pageTextContains($this->webUser->getAccountName()); // Click 'Refresh'. $this->clickLink($this->t('List OpenStack ports')); $this->assertNoErrorMessage(); } // Edit port information. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++, $num++) { // Change port name in mock data. $add[$i]['name'] = 'eni-' . $this->getRandomId(); $this->updatePortMockData($i, $add[$i]['name']); } // Make sure listing. $this->drupalGet("/clouds/openstack/$cloud_context/port"); $this->assertNoErrorMessage(); for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextNotContains($add[$i]['name']); } // Click 'Refresh'. $this->clickLink($this->t('Refresh')); $this->assertSession()->pageTextContains($this->t('Updated ports.')); // Make sure listing. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextContains($add[$i]['name']); } // Delete port in mock data. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->deleteFirstPortMockData(); } // Make sure listing. $this->drupalGet("/clouds/openstack/$cloud_context/port"); $this->assertNoErrorMessage(); for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextContains($add[$i]['name']); } // Click 'Refresh'. $this->clickLink($this->t('Refresh')); $this->assertSession()->pageTextContains($this->t('Updated ports.')); // Make sure listing. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextNotContains($add[$i]['name']); } } /** * Test updating all ports. * * @throws \Behat\Mink\Exception\ExpectationException * @throws \Exception */ public function testUpdateAllPortList(): void { $cloud_configs = []; // List port for OpenStack. $this->drupalGet('/clouds/openstack/port'); $this->assertNoErrorMessage(); // Create Cloud Config. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->cloudContext = $this->random->name(8); $cloud_config = $this->createCloudConfigTestEntity($this->cloudContext, $this->cloudConfig->get('field_use_openstack_ec2_api')->value); $cloud_configs[] = $cloud_config; } // Add a new port. foreach ($cloud_configs ?: [] as $cloud_config) { $cloud_context = $cloud_config->getCloudContext(); $add = $this->createPortTestFormData(self::OPENSTACK_PORT_REPEAT_COUNT); for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->reloadMockData(); $this->addPortMockData($add[$i], $cloud_context, $this->webUser->id()); } } // Make sure listing. $this->drupalGet('/clouds/openstack/port'); $this->assertNoErrorMessage(); for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextNotContains($add[$i]['name']); } // Click 'Refresh'. $this->clickLink($this->t('Refresh')); foreach ($cloud_configs ?: [] as $cloud_config) { $this->assertSession()->pageTextContains($this->t('Updated @resources of @cloud_config cloud service provider.', [ '@resources' => 'Ports', '@cloud_config' => $cloud_config->getName(), ])); } // Make sure listing. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextContains($add[$i]['name']); } // Make sure detailed and edit view. foreach ($cloud_configs ?: [] as $cloud_config) { $cloud_context = $cloud_config->getCloudContext(); for ($i = 0, $num = 1; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++, $num++) { // Confirm the detailed view. $this->drupalGet("/clouds/openstack/${cloud_context}/port/${num}"); $this->assertSession()->linkExists($this->t('Edit')); $this->assertSession()->linkByHrefExists("/clouds/openstack/${cloud_context}/port/${num}/edit"); $this->assertSession()->linkExists($this->t('Delete')); $this->assertSession()->linkByHrefExists("/clouds/openstack/${cloud_context}/port/${num}/delete"); $this->assertSession()->linkExists($this->t('List OpenStack ports')); // Click 'List OpenStack ports'. $this->clickLink($this->t('List OpenStack ports')); $this->assertNoErrorMessage(); } } // Edit Port information. foreach ($cloud_configs ?: [] as $cloud_config) { for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++, $num++) { // Change port name in mock data. $add[$i]['name'] = "eni-{$this->getRandomId()}"; $this->updatePortMockData($i, $add[$i]['name']); } } // Make sure listing. $this->drupalGet('/clouds/openstack/port'); $this->assertNoErrorMessage(); for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextNotContains($add[$i]['name']); } // Click 'Refresh'. $this->clickLink($this->t('Refresh')); foreach ($cloud_configs ?: [] as $cloud_config) { $this->assertSession()->pageTextContains($this->t('Updated @resources of @cloud_config cloud service provider.', [ '@resources' => 'Ports', '@cloud_config' => $cloud_config->getName(), ])); } // Make sure listing. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextContains($add[$i]['name']); } // Delete port in mock data. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->deleteFirstPortMockData(); } // Make sure listing. $this->drupalGet('/clouds/openstack/port'); $this->assertNoErrorMessage(); for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextContains($add[$i]['name']); } // Click 'Refresh'. $this->clickLink($this->t('Refresh')); foreach ($cloud_configs ?: [] as $cloud_config) { $this->assertSession()->pageTextContains($this->t('Updated @resources of @cloud_config cloud service provider.', [ '@resources' => 'Ports', '@cloud_config' => $cloud_config->getName(), ])); } // Make sure listing. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextNotContains($add[$i]['name']); } } /** * Check if service type is EC2 or REST. * * @return bool * TRUE if cloud config type is EC2 API, otherwise FALSE. */ protected function getEc2ServiceType(): bool { // OpenStack Port uses REST only. return FALSE; } } modules/cloud_service_providers/openstack/tests/src/Traits/OpenStackTestEntityTrait.php +96 −6 Original line number Diff line number Diff line Loading @@ -255,9 +255,9 @@ trait OpenStackTestEntityTrait { * @param string $name * The network name. * @param string $network_id * The network id. * The network ID. * @param string $project_id * The project id. * The project ID. * @param string $admin_state_up * The admin state up. * @param string $shared Loading Loading @@ -320,13 +320,13 @@ trait OpenStackTestEntityTrait { * @param string $name * The subnet name. * @param string $subnet_id * The subnet id. * The subnet ID. * @param string $network_id * The network id. * The network ID. * @param string $project_id * The project id. * The project ID. * @param string $subnet_pool_id * The subnet pool id. * The subnet pool ID. * @param string $ip_version * The ip version. * @param string $cidr Loading Loading @@ -387,4 +387,94 @@ trait OpenStackTestEntityTrait { ]); } /** * Create an Open Stack port test entity. * * @param string $class * The network class. * @param int $index * The Index. * @param string $cloud_context * The cloud context. * @param string $name * The network name. * @param string $port_id * The port ID. * @param string $network_id * The network ID. * @param string $project_id * The project ID. * @param string $mac_address * The mac address. * @param string $admin_state_up * The admin state up. * @param string $port_security_enabled * The port security enabled. * @param string $dns_name * The dns name. * @param string $dns_assignment * The dns assignment. * @param array $fixed_ips * The fixed ips. * @param string $device_owner * The device owner. * @param string $device_id * The device ID. * @param array $security_groups * The security groups. * * @return \Drupal\cloud\Entity\CloudContentEntityBase * The network entity. * * @throws \Exception */ protected function createPortTestEntity( string $class, int $index = 0, string $cloud_context = '', string $name = '', string $port_id = '', string $network_id = '', string $project_id = '', string $mac_address = '', string $admin_state_up = '', string $port_security_enabled = '', string $dns_name = '', string $dns_assignment = '', array $fixed_ips = [], string $device_owner = '', string $device_id = '', array $security_groups = [] ): CloudContentEntityBase { $timestamp = time(); return $this->createTestEntity($class, [ 'cloud_context' => $cloud_context, 'name' => $name ?: sprintf('port-entity #%d - %s - %s', $index + 1, date('Y/m/d H:i:s'), $this->random->name(32, TRUE)), 'port_id' => $port_id ?: 'port-' . $this->getRandomId(), 'network_id' => $network_id ?: 'network-' . $this->getRandomId(), 'project_id' => $project_id ?: 'project-' . $this->getRandomId(), 'mac_address' => $mac_address, 'admin_state_up' => $admin_state_up, 'port_security_enabled' => $port_security_enabled, 'dns_name' => $dns_name, 'dns_assignment' => $dns_assignment, 'fixed_ips' => $fixed_ips, 'device_owner' => $device_owner, 'device_id' => $device_id, 'security_groups' => $security_groups, 'binding_vnic_type' => '', 'binding_host_id' => '', 'binding_profile' => '', 'binding_vif_type' => '', 'binding_vif_details' => '', 'allowed_address_pairs' => '', 'status' => 'ACTIVE', 'created' => $timestamp, 'changed' => $timestamp, 'refreshed' => $timestamp, 'uid' => $this->loggedInUser->id(), ]); } } modules/cloud_service_providers/openstack/tests/src/Traits/OpenStackTestFormDataTrait.php +53 −0 Original line number Diff line number Diff line Loading @@ -488,4 +488,57 @@ trait OpenStackTestFormDataTrait { return $subnets; } /** * Create port test data. * * @param int $repeat_count * Repeat count. * * @return array * test data array. */ protected function createPortTestFormData(int $repeat_count): array { $data = []; $ip_address_or_subnets = [ 'subnet', 'fixed_ip', ]; $ip_address_or_subnet = $ip_address_or_subnets[random_int(0, 1)]; for ($i = 0, $num = 1; $i < $repeat_count; $i++, $num++) { $ip_address_or_subnet = $ip_address_or_subnets[$i]; $data[$i] = [ 'name' => "port-name #$num - {$this->random->name(32, TRUE)}", 'network_id' => "network-{$this->getRandomId()}", 'device_id' => "device-{$this->getRandomId()}", 'device_owner' => 'network:{$this->getRandomId()}', 'ip_address_or_subnet' => $ip_address_or_subnet, 'subnet' => "subnet-{$this->getRandomId()}", 'fixed_ips' => Utils::getRandomPublicIp(), ]; } return $data; } /** * Create random port data. * * @return array * Random port data. * * @throws \Exception */ protected function createPortsRandomTestFormData(): array { $ports = []; $count = random_int(1, 10); for ($i = 0, $num = 1; $i < $count; $i++, $num++) { $ports[] = [ 'PortId' => "port-{$this->getRandomId()}", 'Name' => sprintf('port-random-data #%d - %s - %s', $num, date('Y/m/d H:i:s'), $this->random->name(32, TRUE)), ]; } return $ports; } } Loading
modules/cloud_service_providers/openstack/src/Form/OpenStackPortEditForm.php +1 −1 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ class OpenStackPortEditForm extends AwsCloudContentForm { protected $openStackOperationsService; /** * OpenStackPortCreateForm constructor. * OpenStackPortEditForm constructor. * * @param \Drupal\aws_cloud\Service\AwsCloud\AwsCloudOperationsServiceInterface $aws_cloud_operations_service * The AWS Cloud Operations service. Loading
modules/cloud_service_providers/openstack/src/Service/Rest/OpenStackServiceMock.php +39 −0 Original line number Diff line number Diff line Loading @@ -718,6 +718,45 @@ class OpenStackServiceMock extends OpenStackService { return $this->getMockData(__FUNCTION__); } /** * Create an OpenStack port. * * @param array $params * Parameters to pass to the API. * * @return array * The port create API response. */ public function createPort(array $params = []): array { return $this->getMockData(__FUNCTION__); } /** * Update an OpenStack port. * * @param array $params * Parameters to pass to the API. * * @return array * The port update API response. */ public function updatePort(array $params = []): array { return $this->getMockData(__FUNCTION__); } /** * Delete an OpenStack port. * * @param array $params * Parameters to pass to the API. * * @return array * The port delete API response. */ public function deletePort(array $params = []): array { return $this->getMockData(__FUNCTION__); } /** * Get routers. * Loading
modules/cloud_service_providers/openstack/tests/src/Functional/OpenStack/OpenStackPortTest.php 0 → 100644 +440 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\openstack\Functional\OpenStack; use Drupal\openstack\Entity\OpenStackNetwork; use Drupal\openstack\Entity\OpenStackPort; use Drupal\openstack\Entity\OpenStackSubnet; use Drupal\Tests\openstack\Functional\OpenStackTestBase; /** * Tests OpenStack port. * * @group OpenStack */ class OpenStackPortTest extends OpenStackTestBase { public const OPENSTACK_PORT_REPEAT_COUNT = 2; /** * {@inheritdoc} */ protected function getPermissions(): array { return [ 'view all cloud service providers', 'list openstack port', 'add openstack port', 'view any openstack port', 'edit any openstack port', 'delete any openstack port', ]; } /** * {@inheritdoc} * * @throws \Exception */ protected function getMockDataTemplateVars(): array { return [ 'port_id' => 'port-' . $this->getRandomId(), 'network_id' => 'network-' . $this->getRandomId(), 'project_id' => $this->cloudConfig->get('field_project_id')->value, 'create_time' => date('c'), ]; } /** * Tests CRUD for port information. * * @throws \Behat\Mink\Exception\ExpectationException * @throws \Exception */ public function testPort(): void { $cloud_context = $this->cloudContext; // List port for OpenStack. $this->drupalGet("/clouds/openstack/$cloud_context/port"); $this->assertNoErrorMessage(); // Create random networks. $networks = $this->createNetworksRandomTestFormData(); $this->updateDescribeNetworksMockData($networks); // Create the network entities. $i = 1; foreach ($networks ?: [] as $network) { $this->createNetworkTestEntity(OpenStackNetwork::class, $i++, $cloud_context, $network['Name'], $network['NetworkId']); // Create random subnets. $subnets = $this->createopenstackSubnetsRandomTestFormData(); $this->updateDescribeSubnetsMockData($subnets); $subnet_index = 1; foreach ($subnets ?: [] as $subnet) { $this->createOpenStackSubnetTestEntity(OpenStackSubnet::class, $subnet_index++, $cloud_context, $subnet['Name'], $subnet['SubnetId'], $network['NetworkId']); $subnet_index++; } $i++; } // Add a new port. $add = $this->createPortTestFormData(self::OPENSTACK_PORT_REPEAT_COUNT); for ($i = 0, $num = 1; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++, $num++) { $this->addPortMockData($add[$i], $cloud_context, $this->webUser->id()); // Set network ID. $add[$i]['network_id'] = $networks[array_rand($networks)]['NetworkId']; // Set subnet ID. $add[$i]['subnet'] = $subnets[array_rand($subnets)]['SubnetId']; $this->drupalGet("/clouds/openstack/$cloud_context/port/add"); $this->submitForm( $add[$i], $this->t('Save')); $this->assertNoErrorMessage(); $t_args = ['@type' => 'Port', '%label' => $add[$i]['name']]; $this->assertSession()->pageTextContains(strip_tags($this->t('The @type %label has been created.', $t_args))); // Make sure View. $this->drupalGet("/clouds/openstack/$cloud_context/port/$num"); $this->assertNoErrorMessage(); // Make sure listing. $this->drupalGet("/clouds/openstack/$cloud_context/port"); $this->assertNoErrorMessage(); for ($j = 0; $j < $num; $j++) { $this->assertSession()->pageTextContains($add[$j]['name']); } // Make sure uid. $this->drupalGet("/clouds/openstack/$cloud_context/port/$num"); $this->assertSession()->pageTextContains($this->webUser->getAccountName()); } for ($i = 0, $num = 1; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++, $num++) { // Make sure the all port listing exists. $this->drupalGet('/clouds/openstack/port'); $this->assertNoErrorMessage(); for ($j = 0; $j < $num; $j++) { $this->assertSession()->pageTextContains($add[$j]['name']); } } // Edit port information. $edit = $this->createPortTestFormData(self::OPENSTACK_PORT_REPEAT_COUNT); for ($i = 0, $num = 1; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++, $num++) { unset( $edit[$i]['network_id'], $edit[$i]['subnet'], $edit[$i]['fixed_ips'], $edit[$i]['device_id'], $edit[$i]['device_owner'], $edit[$i]['ip_address_or_subnet'], ); $this->updatePortMockData($i, $edit[$i]['name']); $this->drupalGet("/clouds/openstack/$cloud_context/port/$num/edit"); $this->submitForm( $edit[$i], $this->t('Save')); $this->assertNoErrorMessage(); $t_args = ['@type' => 'Port', '%label' => $edit[$i]['name']]; $this->assertSession()->pageTextContains(strip_tags($this->t('The @type %label has been updated.', $t_args))); $this->drupalGet("/clouds/openstack/$cloud_context/port"); $this->assertNoErrorMessage(); $this->assertSession()->pageTextContains($edit[$i]['name']); // Make sure listing. $this->drupalGet("/clouds/openstack/$cloud_context/port"); $this->assertNoErrorMessage(); for ($j = 0; $j < $num; $j++) { $this->assertSession()->pageTextContains($edit[$i]['name']); } // Make sure uid. $this->drupalGet("/clouds/openstack/$cloud_context/port/$num"); $this->assertSession()->pageTextContains($this->webUser->getAccountName()); } // Delete port. for ($i = 0, $num = 1; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++, $num++) { $this->drupalGet("/clouds/openstack/$cloud_context/port/$num/delete"); $this->assertNoErrorMessage(); $this->drupalGet("/clouds/openstack/$cloud_context/port/$num/delete"); $this->submitForm( [], $this->t('Delete')); $this->assertNoErrorMessage(); $t_args = ['@type' => 'Port', '@label' => $edit[$i]['name']]; $this->assertSession()->pageTextContains(strip_tags($this->t('The @type @label has been deleted.', $t_args))); // Make sure listing. $this->drupalGet("/clouds/openstack/$cloud_context/port"); $this->assertNoErrorMessage(); } } /** * Tests deleting ports with bulk operation. * * @throws \Exception */ public function testPortBulk(): void { for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { // Create port. $ports = $this->createPortsRandomTestFormData(); $index = 0; $entities = []; foreach ($ports ?: [] as $port) { $entities[] = $this->createPortTestEntity(OpenStackPort::class, $index++, $this->cloudContext, $port['Name']); } // The first parameter type should be 'port' in OpenStack. $this->runTestEntityBulk('port', $entities); } } /** * Test updating port. * * @throws \Behat\Mink\Exception\ExpectationException */ public function testUpdatePortList(): void { $cloud_context = $this->cloudContext; // Add a new port. $add = $this->createPortTestFormData(self::OPENSTACK_PORT_REPEAT_COUNT); for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->reloadMockData(); $this->addPortMockData($add[$i], $cloud_context, $this->webUser->id()); } // Make sure listing. $this->drupalGet("/clouds/openstack/$cloud_context/port"); $this->assertNoErrorMessage(); for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextNotContains($add[$i]['name']); } // Click 'Refresh'. $this->clickLink($this->t('Refresh')); $this->assertSession()->pageTextContains($this->t('Updated ports.')); // Make sure listing. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextContains($add[$i]['name']); } // Make sure detailed and edit view. for ($i = 0, $num = 1; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++, $num++) { // Confirm the detailed view. $this->drupalGet("/clouds/openstack/$cloud_context/port/$num"); $this->assertSession()->linkExists($this->t('Edit')); $this->assertSession()->linkByHrefExists("/clouds/openstack/$cloud_context/port/$num/edit"); $this->assertSession()->linkExists($this->t('Delete')); $this->assertSession()->linkByHrefExists("/clouds/openstack/$cloud_context/port/$num/delete"); $this->assertSession()->linkExists($this->t('List OpenStack ports')); // Make sure uid. $this->assertSession()->pageTextContains($this->webUser->getAccountName()); // Click 'Refresh'. $this->clickLink($this->t('List OpenStack ports')); $this->assertNoErrorMessage(); } // Edit port information. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++, $num++) { // Change port name in mock data. $add[$i]['name'] = 'eni-' . $this->getRandomId(); $this->updatePortMockData($i, $add[$i]['name']); } // Make sure listing. $this->drupalGet("/clouds/openstack/$cloud_context/port"); $this->assertNoErrorMessage(); for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextNotContains($add[$i]['name']); } // Click 'Refresh'. $this->clickLink($this->t('Refresh')); $this->assertSession()->pageTextContains($this->t('Updated ports.')); // Make sure listing. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextContains($add[$i]['name']); } // Delete port in mock data. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->deleteFirstPortMockData(); } // Make sure listing. $this->drupalGet("/clouds/openstack/$cloud_context/port"); $this->assertNoErrorMessage(); for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextContains($add[$i]['name']); } // Click 'Refresh'. $this->clickLink($this->t('Refresh')); $this->assertSession()->pageTextContains($this->t('Updated ports.')); // Make sure listing. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextNotContains($add[$i]['name']); } } /** * Test updating all ports. * * @throws \Behat\Mink\Exception\ExpectationException * @throws \Exception */ public function testUpdateAllPortList(): void { $cloud_configs = []; // List port for OpenStack. $this->drupalGet('/clouds/openstack/port'); $this->assertNoErrorMessage(); // Create Cloud Config. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->cloudContext = $this->random->name(8); $cloud_config = $this->createCloudConfigTestEntity($this->cloudContext, $this->cloudConfig->get('field_use_openstack_ec2_api')->value); $cloud_configs[] = $cloud_config; } // Add a new port. foreach ($cloud_configs ?: [] as $cloud_config) { $cloud_context = $cloud_config->getCloudContext(); $add = $this->createPortTestFormData(self::OPENSTACK_PORT_REPEAT_COUNT); for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->reloadMockData(); $this->addPortMockData($add[$i], $cloud_context, $this->webUser->id()); } } // Make sure listing. $this->drupalGet('/clouds/openstack/port'); $this->assertNoErrorMessage(); for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextNotContains($add[$i]['name']); } // Click 'Refresh'. $this->clickLink($this->t('Refresh')); foreach ($cloud_configs ?: [] as $cloud_config) { $this->assertSession()->pageTextContains($this->t('Updated @resources of @cloud_config cloud service provider.', [ '@resources' => 'Ports', '@cloud_config' => $cloud_config->getName(), ])); } // Make sure listing. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextContains($add[$i]['name']); } // Make sure detailed and edit view. foreach ($cloud_configs ?: [] as $cloud_config) { $cloud_context = $cloud_config->getCloudContext(); for ($i = 0, $num = 1; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++, $num++) { // Confirm the detailed view. $this->drupalGet("/clouds/openstack/${cloud_context}/port/${num}"); $this->assertSession()->linkExists($this->t('Edit')); $this->assertSession()->linkByHrefExists("/clouds/openstack/${cloud_context}/port/${num}/edit"); $this->assertSession()->linkExists($this->t('Delete')); $this->assertSession()->linkByHrefExists("/clouds/openstack/${cloud_context}/port/${num}/delete"); $this->assertSession()->linkExists($this->t('List OpenStack ports')); // Click 'List OpenStack ports'. $this->clickLink($this->t('List OpenStack ports')); $this->assertNoErrorMessage(); } } // Edit Port information. foreach ($cloud_configs ?: [] as $cloud_config) { for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++, $num++) { // Change port name in mock data. $add[$i]['name'] = "eni-{$this->getRandomId()}"; $this->updatePortMockData($i, $add[$i]['name']); } } // Make sure listing. $this->drupalGet('/clouds/openstack/port'); $this->assertNoErrorMessage(); for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextNotContains($add[$i]['name']); } // Click 'Refresh'. $this->clickLink($this->t('Refresh')); foreach ($cloud_configs ?: [] as $cloud_config) { $this->assertSession()->pageTextContains($this->t('Updated @resources of @cloud_config cloud service provider.', [ '@resources' => 'Ports', '@cloud_config' => $cloud_config->getName(), ])); } // Make sure listing. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextContains($add[$i]['name']); } // Delete port in mock data. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->deleteFirstPortMockData(); } // Make sure listing. $this->drupalGet('/clouds/openstack/port'); $this->assertNoErrorMessage(); for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextContains($add[$i]['name']); } // Click 'Refresh'. $this->clickLink($this->t('Refresh')); foreach ($cloud_configs ?: [] as $cloud_config) { $this->assertSession()->pageTextContains($this->t('Updated @resources of @cloud_config cloud service provider.', [ '@resources' => 'Ports', '@cloud_config' => $cloud_config->getName(), ])); } // Make sure listing. for ($i = 0; $i < self::OPENSTACK_PORT_REPEAT_COUNT; $i++) { $this->assertSession()->pageTextNotContains($add[$i]['name']); } } /** * Check if service type is EC2 or REST. * * @return bool * TRUE if cloud config type is EC2 API, otherwise FALSE. */ protected function getEc2ServiceType(): bool { // OpenStack Port uses REST only. return FALSE; } }
modules/cloud_service_providers/openstack/tests/src/Traits/OpenStackTestEntityTrait.php +96 −6 Original line number Diff line number Diff line Loading @@ -255,9 +255,9 @@ trait OpenStackTestEntityTrait { * @param string $name * The network name. * @param string $network_id * The network id. * The network ID. * @param string $project_id * The project id. * The project ID. * @param string $admin_state_up * The admin state up. * @param string $shared Loading Loading @@ -320,13 +320,13 @@ trait OpenStackTestEntityTrait { * @param string $name * The subnet name. * @param string $subnet_id * The subnet id. * The subnet ID. * @param string $network_id * The network id. * The network ID. * @param string $project_id * The project id. * The project ID. * @param string $subnet_pool_id * The subnet pool id. * The subnet pool ID. * @param string $ip_version * The ip version. * @param string $cidr Loading Loading @@ -387,4 +387,94 @@ trait OpenStackTestEntityTrait { ]); } /** * Create an Open Stack port test entity. * * @param string $class * The network class. * @param int $index * The Index. * @param string $cloud_context * The cloud context. * @param string $name * The network name. * @param string $port_id * The port ID. * @param string $network_id * The network ID. * @param string $project_id * The project ID. * @param string $mac_address * The mac address. * @param string $admin_state_up * The admin state up. * @param string $port_security_enabled * The port security enabled. * @param string $dns_name * The dns name. * @param string $dns_assignment * The dns assignment. * @param array $fixed_ips * The fixed ips. * @param string $device_owner * The device owner. * @param string $device_id * The device ID. * @param array $security_groups * The security groups. * * @return \Drupal\cloud\Entity\CloudContentEntityBase * The network entity. * * @throws \Exception */ protected function createPortTestEntity( string $class, int $index = 0, string $cloud_context = '', string $name = '', string $port_id = '', string $network_id = '', string $project_id = '', string $mac_address = '', string $admin_state_up = '', string $port_security_enabled = '', string $dns_name = '', string $dns_assignment = '', array $fixed_ips = [], string $device_owner = '', string $device_id = '', array $security_groups = [] ): CloudContentEntityBase { $timestamp = time(); return $this->createTestEntity($class, [ 'cloud_context' => $cloud_context, 'name' => $name ?: sprintf('port-entity #%d - %s - %s', $index + 1, date('Y/m/d H:i:s'), $this->random->name(32, TRUE)), 'port_id' => $port_id ?: 'port-' . $this->getRandomId(), 'network_id' => $network_id ?: 'network-' . $this->getRandomId(), 'project_id' => $project_id ?: 'project-' . $this->getRandomId(), 'mac_address' => $mac_address, 'admin_state_up' => $admin_state_up, 'port_security_enabled' => $port_security_enabled, 'dns_name' => $dns_name, 'dns_assignment' => $dns_assignment, 'fixed_ips' => $fixed_ips, 'device_owner' => $device_owner, 'device_id' => $device_id, 'security_groups' => $security_groups, 'binding_vnic_type' => '', 'binding_host_id' => '', 'binding_profile' => '', 'binding_vif_type' => '', 'binding_vif_details' => '', 'allowed_address_pairs' => '', 'status' => 'ACTIVE', 'created' => $timestamp, 'changed' => $timestamp, 'refreshed' => $timestamp, 'uid' => $this->loggedInUser->id(), ]); } }
modules/cloud_service_providers/openstack/tests/src/Traits/OpenStackTestFormDataTrait.php +53 −0 Original line number Diff line number Diff line Loading @@ -488,4 +488,57 @@ trait OpenStackTestFormDataTrait { return $subnets; } /** * Create port test data. * * @param int $repeat_count * Repeat count. * * @return array * test data array. */ protected function createPortTestFormData(int $repeat_count): array { $data = []; $ip_address_or_subnets = [ 'subnet', 'fixed_ip', ]; $ip_address_or_subnet = $ip_address_or_subnets[random_int(0, 1)]; for ($i = 0, $num = 1; $i < $repeat_count; $i++, $num++) { $ip_address_or_subnet = $ip_address_or_subnets[$i]; $data[$i] = [ 'name' => "port-name #$num - {$this->random->name(32, TRUE)}", 'network_id' => "network-{$this->getRandomId()}", 'device_id' => "device-{$this->getRandomId()}", 'device_owner' => 'network:{$this->getRandomId()}', 'ip_address_or_subnet' => $ip_address_or_subnet, 'subnet' => "subnet-{$this->getRandomId()}", 'fixed_ips' => Utils::getRandomPublicIp(), ]; } return $data; } /** * Create random port data. * * @return array * Random port data. * * @throws \Exception */ protected function createPortsRandomTestFormData(): array { $ports = []; $count = random_int(1, 10); for ($i = 0, $num = 1; $i < $count; $i++, $num++) { $ports[] = [ 'PortId' => "port-{$this->getRandomId()}", 'Name' => sprintf('port-random-data #%d - %s - %s', $num, date('Y/m/d H:i:s'), $this->random->name(32, TRUE)), ]; } return $ports; } }