cloud-8.x-2.0-beta1/modules/cloud_service_providers/aws_cloud/tests/src/Unit/Plugin/cloud/server_template/AwsCloudServerTemplatePluginTest.php

modules/cloud_service_providers/aws_cloud/tests/src/Unit/Plugin/cloud/server_template/AwsCloudServerTemplatePluginTest.php
<?php

namespace Drupal\Tests\aws_cloud\Unit\Plugin\cloud\server_template;

use Drupal\Tests\UnitTestCase;
use Drupal\Tests\aws_cloud\Traits\AwsCloudTestEntityTrait;

use Drupal\Component\Utility\Random;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\Messenger;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\Query\QueryInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\StringTranslation\TranslationInterface;
use Drupal\Component\Uuid\UuidInterface;
use Drupal\cloud\Entity\CloudServerTemplateInterface;
use Drupal\cloud\Plugin\cloud\config\CloudConfigPluginManagerInterface;
use Drupal\cloud\Service\EntityLinkRendererInterface;
use Drupal\aws_cloud\Entity\Ec2\ImageInterface;
use Drupal\aws_cloud\Entity\Ec2\KeyPairInterface;
use Drupal\aws_cloud\Entity\Ec2\NetworkInterfaceInterface;
use Drupal\aws_cloud\Entity\Ec2\SecurityGroupInterface;
use Drupal\aws_cloud\Plugin\cloud\server_template\AwsCloudServerTemplatePlugin;
use Drupal\aws_cloud\Service\Ec2\Ec2ServiceInterface;
use Drupal\aws_cloud\Plugin\Field\FieldType\Tag;

/**
 * Tests AWS Cloud Template Plugin.
 *
 * @group AWS Cloud
 */
class AwsCloudServerTemplatePluginTest extends UnitTestCase {

  use AwsCloudTestEntityTrait;

  // Amazon VPC Limits - Security groups per VPC (per region).
  const MAX_SECURITY_GROUPS_COUNT = 500;

  /**
   * Plugin.
   *
   * @var string
   */
  private $plugin;

  /**
   * AWS Cloud EC2 Service mock.
   *
   * @var \Drupal\aws_cloud\Service\Ec2\Ec2ServiceInterface
   */
  private $ec2ServiceMock;

  /**
   * Creating random data utility.
   *
   * @var \Drupal\Component\Utility\Random
   */
  private $random;

  /**
   * {@inheritdoc}
   */
  protected function setUp() {
    $this->ec2ServiceMock = $this->createMock(Ec2ServiceInterface::class);

    $mock_query = $this->createMock(QueryInterface::class);
    $mock_query->expects($this->any())
      ->method('condition')
      ->will($this->returnValue($mock_query));

    $mock_query->expects($this->any())
      ->method('execute')
      ->will($this->returnValue([]));

    $mock_storage = $this->createMock(EntityStorageInterface::class);
    $mock_storage->expects($this->any())
      ->method('getQuery')
      ->will($this->returnValue($mock_query));

    $mock_storage->expects($this->any())
      ->method('loadMultiple')
      ->will($this->returnValue([]));

    $mock_entity_type_manager = $this->createMock(EntityTypeManagerInterface::class);
    $mock_entity_type_manager->expects($this->any())
      ->method('getStorage')
      ->will($this->returnValue($mock_storage));

    $mock_uuid = $this->createMock(UuidInterface::class);
    $mock_uuid->expects($this->any())
      ->method('generate')
      ->will($this->returnValue(''));

    $mock_user = $this->createMock(AccountProxyInterface::class);
    $mock_config_factory = $this->createMock(ConfigFactoryInterface::class);
    $mock_string_translation = $this->createMock(TranslationInterface::class);
    $mock_cloud_config_plugin_manager = $this->createMock(CloudConfigPluginManagerInterface::class);
    $mock_entity_link_renderer = $this->createMock(EntityLinkRendererInterface::class);

    $this->plugin = new AwsCloudServerTemplatePlugin(
      [], '', [],
      $this->ec2ServiceMock,
      $this->getMockBuilder(Messenger::class)
        ->disableOriginalConstructor()
        ->getMock(),
      $mock_entity_type_manager,
      $mock_uuid,
      $mock_user,
      $mock_config_factory,
      $mock_string_translation,
      $mock_cloud_config_plugin_manager,
      $mock_entity_link_renderer
    );

    $this->random = new Random();
  }

  /**
   * Tests launching a instance.
   */
  public function testLaunch() {
    $random = $this->random;

    // Mock object of Image.
    $mock_image = $this->createMock(ImageInterface::class);
    $image_value_map = [
      ['image_id', (object) ['value' => 'ami-' . $this->getRandomAwsId()]],
      ['root_device_type', 'ebs'],
    ];
    $mock_image->expects($this->any())
      ->method('get')
      ->will($this->returnValueMap($image_value_map));

    // Mock object of KeyPair.
    $mock_ssh_key = $this->createMock(KeyPairInterface::class);
    $ssh_key_value_map = [
      ['key_pair_name', (object) ['value' => $random->name(8, TRUE)]],
    ];
    $mock_ssh_key->expects($this->any())
      ->method('get')
      ->will($this->returnValueMap($ssh_key_value_map));

    // Mock object of NetworkInterface.
    $mock_network = $this->createMock(NetworkInterfaceInterface::class);
    $network_interface_id = 'eni-' . $this->getRandomAwsId();
    $mock_network->expects($this->any())
      ->method('getNetworkInterfaceId')
      ->will($this->returnValue($network_interface_id));

    $vpc_id = 'vpc-' . $this->getRandomAwsId();
    $field_security_groups_test_cases = $this->createFieldSecurityGroupsTestCases($vpc_id);
    $subnet_id = 'subnet-' . $this->getRandomAwsId();

    // Create random tags.
    $mock_tags = $this->createRandomTags();
    $aws_tags = $this->convertToAwsTags($mock_tags);

    // Add Name tag.
    $template_name = $random->name(8, TRUE);
    $aws_tags[] = [
      'Key' => 'Name',
      'Value' => $template_name,
    ];

    // Run test cases.
    foreach ($field_security_groups_test_cases as $field_security_groups_test_case) {
      $mock_template = $this->createMock(CloudServerTemplateInterface::class);
      $template_value_map = [
        ['field_test_only', (object) ['value' => '1']],
        ['field_image_id', (object) ['value' => $mock_image->getImageId()]],
        ['field_max_count', (object) ['value' => 1]],
        ['field_min_count', (object) ['value' => 1]],
        ['field_monitoring', (object) ['value' => '1']],
        ['field_instance_type', (object) ['value' => $random->name(5, TRUE)]],
        ['field_ssh_key', (object) ['entity' => $mock_ssh_key]],
        [
          'field_kernel_id',
          (object) ['value' => 'aki-' . $this->getRandomAwsId()],
        ],
        ['field_ram', (object) ['value' => 'ari-' . $this->getRandomAwsId()]],
        ['field_user_data', (object) ['value' => $random->string(32, TRUE)]],
        [
          'field_availability_zone',
          (object) ['value' => $random->name(7, TRUE)],
        ],
        [
          'field_security_group',
          $this->extractArrayItem($field_security_groups_test_case, 0),
        ],
        ['field_network', (object) ['entity' => $mock_network]],
        ['field_subnet', (object) ['value' => $subnet_id]],
        ['field_instance_shutdown_behavior', (object) ['value' => '1']],
        ['field_vpc', (object) ['value' => $vpc_id]],
        ['field_iam_role', (object) ['value' => '']],
        ['field_tags', $mock_tags],
      ];
      $mock_template->expects($this->any())
        ->method('get')
        ->will($this->returnValueMap($template_value_map));

      $mock_template->expects($this->any())
        ->method('getName')
        ->will($this->returnValue($template_name));

      // Assert followings for the first argument of method runInstances,
      // 1. Has key SecurityGroups,
      // 2. Doesn't have key SecurityGroup,
      // 3. Contains the array of group1 and group2,
      // 4. Has key SubnetId,
      // 5. Contains subnet_id.
      $this->ec2ServiceMock
        ->expects($this->any())
        ->method('runInstances')
        ->with(
          $this->logicalAnd(
            $this->arrayHasKey('SecurityGroupIds'),
            $this->logicalNot($this->arrayHasKey('SecurityGroups')),
            $this->contains($this->extractArrayItem($field_security_groups_test_case, 1)),
            $this->arrayHasKey('SubnetId'),
            $this->contains($subnet_id)
          ),
          $this->equalTo($aws_tags)
        )
        ->will($this->returnValue(TRUE));

      $return = $this->plugin->launch(
        $mock_template,
        $this->createMock(FormStateInterface::class)
      );
      $this->assertNotNull($return);
    }

  }

  /**
   * Extract array item.
   *
   * @param array $array
   *   Array to be extracted.
   * @param int $index
   *   Index.
   *
   * @return array
   *   Extracted array.
   */
  private function extractArrayItem(array $array, $index) {
    $extracted = [];
    foreach ($array as $item) {
      $extracted[] = $item[$index];
    }

    return $extracted;
  }

  /**
   * Create field security groups test cases.
   *
   * @param string $vpc_id
   *   The ID of vpc.
   *
   * @return array
   *   The test cases of security group.
   */
  private function createFieldSecurityGroupsTestCases($vpc_id) {

    for ($i = 0; $i < self::MAX_SECURITY_GROUPS_COUNT; $i++) {
      // Mock object of SecurityGroup.
      $mock_security_group = $this->createMock(SecurityGroupInterface::class);
      $group_id = 'sg-' . $this->getRandomAwsId();
      $mock_security_group->expects($this->any())
        ->method('getGroupId')
        ->will($this->returnValue($group_id));

      $mock_security_group->expects($this->any())
        ->method('getVpcId')
        ->will($this->returnValue($vpc_id));

      $mock_security_group_and_ids[] = [
        (object) ['entity' => $mock_security_group],
        $group_id,
      ];
    }

    $mock_security_group_and_ids_exclude_first_last = array_slice(
      $mock_security_group_and_ids,
      1,
      count($mock_security_group_and_ids) - 2
    );

    $field_security_groups_test_cases = [];

    // Test cases.
    //
    // Test when Security Groups has the only one item, the first item only.
    // Security Group A (* SELECTED).
    // ...
    // Security Group M.
    // ...
    // Security Group N.
    $field_security_groups_test_cases[] = [reset($mock_security_group_and_ids)];

    // Test when Security Groups has more than two items.
    if (self::MAX_SECURITY_GROUPS_COUNT > 1) {

      // The last item only.
      // Security Group A.
      // ...
      // Security Group M.
      // ...
      // Security Group N (* SELECTED).
      $field_security_groups_test_cases[] = [end($mock_security_group_and_ids)];

      // The first item and the last one only.
      // Security Group A (* SELECTED).
      // ...
      // Security Group M.
      // ...
      // Security Group N (* SELECTED).
      $field_security_groups_test_cases[] = [
        reset($mock_security_group_and_ids),
        end($mock_security_group_and_ids),
      ];

      if (self::MAX_SECURITY_GROUPS_COUNT > 2) {

        // Randomly picking up the only one item.
        // One random item.
        // Security Group A.
        // ...
        // Security Group M (* SELECTED).
        // ...
        // Security Group N.
        $rand_index = array_rand($mock_security_group_and_ids_exclude_first_last);
        $field_security_groups_test_cases[] = [
          // Pickup one index randomly (array index: 1 to the (last index -2))
          $mock_security_group_and_ids_exclude_first_last[$rand_index],
        ];

        // The first item and one random one.
        // Security Group A (* SELECTED).
        // ...
        // Security Group M (* SELECTED).
        // ...
        // Security Group N.
        $rand_index = array_rand($mock_security_group_and_ids_exclude_first_last);
        $field_security_groups_test_cases[] = [
          reset($mock_security_group_and_ids),
          // Pickup one index randomly (array index: 1 to the (last index -2))
          $mock_security_group_and_ids_exclude_first_last[$rand_index],
        ];

        // One random item and the last one.
        // Security Group A.
        // ...
        // Security Group M (* SELECTED).
        // ...
        // Security Group N (* SELECTED).
        $rand_index = array_rand($mock_security_group_and_ids_exclude_first_last);
        $field_security_groups_test_cases[] = [
          // Pickup one index randomly (array index: 1 to the (last index -2))
          $mock_security_group_and_ids_exclude_first_last[$rand_index],
          end($mock_security_group_and_ids),
        ];

        if (self::MAX_SECURITY_GROUPS_COUNT > 3) {

          // Two random items.
          // Security Group A.
          // ...
          // Security Group M1 (* SELECTED).
          // ...
          // Security Group M2 (* SELECTED).
          // ...
          // Security Group N.
          $array_indice = array_rand($mock_security_group_and_ids_exclude_first_last, 2);
          $field_security_groups_test_cases[] = [
            $mock_security_group_and_ids_exclude_first_last[$array_indice[0]],
            $mock_security_group_and_ids_exclude_first_last[$array_indice[1]],
          ];
        }
      }
    }

    return $field_security_groups_test_cases;
  }

  /**
   * Create random tags.
   *
   * @return array
   *   Tag mock objects.
   */
  private function createRandomTags() {
    $mock_tags = [];
    $count = rand(0, 5);
    for ($i = 0; $i < $count; $i++) {
      $mock_tag = $this->getMockBuilder(Tag::class)
        ->disableOriginalConstructor()
        ->getMock();

      $mock_tag->expects($this->any())
        ->method('getTagKey')
        ->will($this->returnValue('key_' . $this->random->name(8, TRUE)));

      $mock_tag->expects($this->any())
        ->method('getTagValue')
        ->will($this->returnValue('value_' . $this->random->name(8, TRUE)));

      $mock_tags[] = $mock_tag;
    }

    return $mock_tags;
  }

  /**
   * Convert mock tag objects to AWS tags.
   *
   * @param array $mock_tags
   *   Mock tag objects.
   *
   * @return array
   *   AWS tags.
   */
  private function convertToAwsTags(array $mock_tags) {
    $tags = [];
    foreach ($mock_tags as $mock_tag) {
      $tags[] = [
        'Key' => $mock_tag->getTagKey(),
        'Value' => $mock_tag->getTagValue(),
      ];
    }

    return $tags;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc