config_preview_deploy-1.0.0-alpha3/tests/src/Kernel/LargeDiffHandlingTest.php

tests/src/Kernel/LargeDiffHandlingTest.php
<?php

declare(strict_types=1);

namespace Drupal\Tests\config_preview_deploy\Kernel;

use Drupal\Component\Serialization\Yaml;
use Drupal\config_preview_deploy\ProductionConfigDeployer;
use Drupal\config_preview_deploy\ConfigDiff;
use Drupal\KernelTests\KernelTestBase;
use SebastianBergmann\Diff\Differ;
use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;

/**
 * Tests handling of large configuration diffs.
 *
 * Verifies that the module can handle complex scenarios with many
 * configuration files and large diffs without performance issues.
 *
 * @group config_preview_deploy
 */
class LargeDiffHandlingTest extends KernelTestBase {

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'config_preview_deploy',
    'system',
    'user',
    'field',
    'node',
    'text',
    'views',
  ];

  /**
   * The production config deployer service.
   */
  protected ProductionConfigDeployer $productionConfigDeployer;

  /**
   * The config diff service.
   */
  protected ConfigDiff $configDiff;

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();
    $this->installEntitySchema('user');
    $this->installEntitySchema('node');
    $this->installConfig(['system', 'user', 'field', 'node', 'text', 'views']);

    $this->productionConfigDeployer = $this->container->get('config_preview_deploy.production_config_deployer');
    $this->configDiff = $this->container->get('config_preview_deploy.config_diff');

    // Fail tests if patch tool is not available.
    $patchTool = $this->container->get('config_preview_deploy.patch_tool');
    if (!$patchTool->isAvailable()) {
      $this->fail('GNU patch tool is required for large diff tests. Install with: apt install patch');
    }
  }

  /**
   * Tests handling of multiple configuration file changes in a single diff.
   */
  public function testMultipleConfigurationFileChanges(): void {
    $activeStorage = $this->container->get('config.storage');

    // Create a diff that modifies multiple configuration files.
    $configs = [
      'system.site' => [
        'original' => $activeStorage->read('system.site'),
        'changes' => ['name' => 'Large Diff Test Site', 'slogan' => 'Testing multiple configs'],
      ],
      'system.performance' => [
        'original' => $activeStorage->read('system.performance'),
        'changes' => ['test_field' => 'Large diff test value'],
      ],
    ];

    $fullDiff = '';
    foreach ($configs as $configName => $configData) {
      $originalYaml = Yaml::encode($configData['original']);

      $modifiedConfig = $configData['original'];
      foreach ($configData['changes'] as $key => $value) {
        $modifiedConfig[$key] = $value;
      }
      $modifiedYaml = Yaml::encode($modifiedConfig);

      $outputBuilder = new UnifiedDiffOutputBuilder(
        "--- a/$configName.yml\n+++ b/$configName.yml\n",
        TRUE
      );
      $differ = new Differ($outputBuilder);
      $fullDiff .= $differ->diff($originalYaml, $modifiedYaml);
    }

    // Test validation of multi-file diff.
    $validation = $this->configDiff->validateDiff($fullDiff);
    $this->assertTrue($validation['valid'], 'Multi-file diff should be valid');
    $this->assertEquals(2, $validation['config_count'], 'Should detect 2 configuration changes');

    // Test applying multi-file diff.
    $results = $this->configDiff->validateAndApplyDiff($fullDiff);
    $this->assertCount(2, $results, 'Should have applied changes to 2 configurations');
    $this->assertArrayHasKey('system.site', $results, 'Should have updated system.site');
    $this->assertArrayHasKey('system.performance', $results, 'Should have updated system.performance');

    // Verify changes were applied correctly.
    $updatedSite = $activeStorage->read('system.site');
    $this->assertEquals('Large Diff Test Site', $updatedSite['name'], 'Site name should be updated');
    $this->assertEquals('Testing multiple configs', $updatedSite['slogan'], 'Slogan should be updated');

    $updatedPerformance = $activeStorage->read('system.performance');
    $this->assertEquals('Large diff test value', $updatedPerformance['test_field'], 'Test field should be updated');
  }

  /**
   * Tests handling of configuration with large amounts of data.
   */
  public function testLargeConfigurationData(): void {
    $activeStorage = $this->container->get('config.storage');

    // Create a configuration with a large amount of data.
    $largeConfig = $activeStorage->read('system.site');

    // Add many fields to simulate a large configuration.
    for ($i = 0; $i < 100; $i++) {
      $largeConfig["large_field_$i"] = str_repeat("Large data content for field $i. ", 50);
    }

    $originalYaml = Yaml::encode($activeStorage->read('system.site'));
    $modifiedYaml = Yaml::encode($largeConfig);

    // Generate diff for large configuration.
    $outputBuilder = new UnifiedDiffOutputBuilder(
      "--- a/system.site.yml\n+++ b/system.site.yml\n",
      TRUE
    );
    $differ = new Differ($outputBuilder);
    $largeDiff = $differ->diff($originalYaml, $modifiedYaml);

    // Verify the diff is substantial.
    $this->assertGreaterThan(10000, strlen($largeDiff), 'Diff should be large (>10KB)');

    // Test validation of large diff.
    $validation = $this->configDiff->validateDiff($largeDiff);
    $this->assertTrue($validation['valid'], 'Large diff should be valid');
    $this->assertGreaterThan(0, $validation['config_count'], 'Should detect configuration changes');

    // Test applying large diff.
    $results = $this->configDiff->validateAndApplyDiff($largeDiff);
    $this->assertArrayHasKey('system.site', $results, 'Should have updated system.site');

    // Verify some of the large data was applied.
    $updatedConfig = $activeStorage->read('system.site');
    $this->assertArrayHasKey('large_field_0', $updatedConfig, 'First large field should exist');
    $this->assertArrayHasKey('large_field_99', $updatedConfig, 'Last large field should exist');
    $this->assertStringContainsString('Large data content for field 0', $updatedConfig['large_field_0'], 'Field content should be correct');
  }

  /**
   * Tests handling of configuration files with complex nested structures.
   */
  public function testComplexNestedConfigurationChanges(): void {
    $activeStorage = $this->container->get('config.storage');

    // Use system.site for complex nested structure changes.
    $originalConfig = $activeStorage->read('system.site');
    $complexConfig = $originalConfig;

    // Add complex nested structure.
    $complexConfig['complex_structure'] = [
      'level1' => [
        'level2' => [
          'level3' => [
            'deeply_nested_field' => 'Deep value',
            'array_field' => ['item1', 'item2', 'item3'],
            'numeric_field' => 12345,
            'boolean_field' => TRUE,
          ],
          'level3_alternative' => [
            'alternative_data' => 'Alternative value',
          ],
        ],
        'level2_sibling' => [
          'sibling_data' => 'Sibling value',
        ],
      ],
      'level1_alternative' => [
        'alternative_structure' => [
          'alt_field' => 'Alt value',
        ],
      ],
    ];

    $originalYaml = Yaml::encode($originalConfig);
    $modifiedYaml = Yaml::encode($complexConfig);

    // Generate diff for complex nested structure.
    $outputBuilder = new UnifiedDiffOutputBuilder(
      "--- a/system.site.yml\n+++ b/system.site.yml\n",
      TRUE
    );
    $differ = new Differ($outputBuilder);
    $complexDiff = $differ->diff($originalYaml, $modifiedYaml);

    // Test validation of complex diff.
    $validation = $this->configDiff->validateDiff($complexDiff);
    $this->assertTrue($validation['valid'], 'Complex nested diff should be valid');

    // Test applying complex diff.
    $results = $this->configDiff->validateAndApplyDiff($complexDiff);
    $this->assertArrayHasKey('system.site', $results, 'Should have updated system.site');

    // Verify complex nested structure was applied correctly.
    $updatedConfig = $activeStorage->read('system.site');
    $this->assertArrayHasKey('complex_structure', $updatedConfig, 'Complex structure should exist');
    $this->assertEquals('Deep value', $updatedConfig['complex_structure']['level1']['level2']['level3']['deeply_nested_field'], 'Deeply nested field should be correct');
    $this->assertEquals(['item1', 'item2', 'item3'], $updatedConfig['complex_structure']['level1']['level2']['level3']['array_field'], 'Array field should be correct');
    $this->assertTrue($updatedConfig['complex_structure']['level1']['level2']['level3']['boolean_field'], 'Boolean field should be correct');
  }

  /**
   * Tests performance with diff validation and application.
   */
  public function testDiffProcessingPerformance(): void {
    $activeStorage = $this->container->get('config.storage');

    // Create a moderately complex diff (simulating real-world usage).
    $configs = [];
    $configNames = ['system.site', 'system.performance'];

    foreach ($configNames as $configName) {
      $originalConfig = $activeStorage->read($configName);
      $modifiedConfig = $originalConfig;

      // Add several fields to each config.
      for ($i = 0; $i < 20; $i++) {
        $modifiedConfig["performance_test_field_$i"] = "Performance test value $i";
      }

      $configs[$configName] = [
        'original' => $originalConfig,
        'modified' => $modifiedConfig,
      ];
    }

    // Generate combined diff.
    $fullDiff = '';
    foreach ($configs as $configName => $configData) {
      $originalYaml = Yaml::encode($configData['original']);
      $modifiedYaml = Yaml::encode($configData['modified']);

      $outputBuilder = new UnifiedDiffOutputBuilder(
        "--- a/$configName.yml\n+++ b/$configName.yml\n",
        TRUE
      );
      $differ = new Differ($outputBuilder);
      $fullDiff .= $differ->diff($originalYaml, $modifiedYaml);
    }

    // Measure validation performance.
    $startTime = microtime(TRUE);
    $validation = $this->configDiff->validateDiff($fullDiff);
    $validationTime = microtime(TRUE) - $startTime;

    $this->assertTrue($validation['valid'], 'Performance test diff should be valid');
    $this->assertLessThan(5.0, $validationTime, 'Validation should complete within 5 seconds');

    // Measure application performance.
    $startTime = microtime(TRUE);
    $results = $this->configDiff->validateAndApplyDiff($fullDiff);
    $applicationTime = microtime(TRUE) - $startTime;

    $this->assertCount(2, $results, 'Should have applied changes to 2 configurations');
    $this->assertLessThan(10.0, $applicationTime, 'Application should complete within 10 seconds');
  }

}

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

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