scenario:
  id: f0e8361f-4d5e-43d9-9223-7af84f42d81f
  context:
    auth:
      type: digest
    base_path: /v1beta2
    host: null
  description: ng_flexible_backup_setting
  name: ng_flexible_backup_setting
steps:
  - operation_id: TidbService_CreateTidb
    request_type: http
    request: |-
      {
        "method": "POST",
        "path": "/tidbs",
        "headers": {},
        "query_params": {},
        "body": {
          "displayName": "sce-ng-flexible-backup-setting",
          "regionId": "{regionId}",
          "minRcu": "5000",
          "maxRcu": "6000",
          "servicePlan": "Premium",
          "cloudProvider": "{cloud_provider}"
        },
        "body_params": {
          "regionId": "region_id",
          "cloud_provider": "cloud_provider"
        },
        "auth": {
          "auth_type": "digest",
          "content": {
            "private_key": "placeholder",
            "public_key": "placeholder"
          }
        }
      }
    expect: |-
      {
        "status_code": 200,
        "cel": ""
      }
    save: |-
      {
        "placeholder": [
          {
            "key": "cluster_1",
            "eval": "body.tidbId"
          }
        ]
      }
    description: "Create a Premium TiDB cluster for flexible backup setting E2E."
    max_retries: 0
    delay_after: 0
    name: "create_premium_cluster"
    continue_on_unexpected: false
    stage: prepare
    meta: "{}"
    generation_id: ""
    order: 0
    case_id: flexible_backup_setting_create_cluster
    case_type: user_defined
    step_type: defined

  - operation_id: PrivateEndpointConnectionService_GetPrivateLinkService
    request_type: http
    request: |-
      {
        "method": "GET",
        "path": "/tidbs/{tidbId}/privateLinkService",
        "headers": {},
        "query_params": {},
        "body": {},
        "path_params": {
          "tidbId": "cluster_1"
        },
        "auth": {
          "auth_type": "digest",
          "content": {
            "private_key": "placeholder",
            "public_key": "placeholder"
          }
        }
      }
    expect: |-
      {
        "status_code": 200,
        "cel": "body.state == 'ACTIVE'"
      }
    save: |-
      {
        "placeholder": [
          {
            "key": "private_link_service_1",
            "eval": "body.serviceName"
          }
        ]
      }
    description: "Wait until the private link service is ACTIVE, matching the readiness gate used by other Premium cluster E2E scenarios."
    max_retries: 120
    delay_after: 30
    name: "wait_private_link_service_active"
    continue_on_unexpected: false
    stage: prepare
    meta: "{}"
    generation_id: ""
    order: 0.5
    case_id: flexible_backup_setting_wait_private_link_service_active
    case_type: user_defined
    step_type: defined

  - operation_id: TidbService_GetTidb
    request_type: http
    request: |-
      {
        "method": "GET",
        "path": "/tidbs/{tidbId}",
        "headers": {},
        "query_params": {},
        "body": {},
        "auth": {
          "auth_type": "digest",
          "content": {
            "private_key": "placeholder",
            "public_key": "placeholder"
          }
        },
        "path_params": {
          "tidbId": "cluster_1"
        }
      }
    expect: |-
      {
        "status_code": 200,
        "cel": "body.state == 'ACTIVE'"
      }
    save: |-
      {
        "placeholder": [
          {
            "key": "flex_daily_backup_time_utc",
            "eval": "saved_placeholder.curr_action_delay_10min_hhmm"
          }
        ]
      }
    description: "Wait until the source cluster is ACTIVE before updating backup settings."
    max_retries: 120
    delay_after: 30
    name: "wait_cluster_active"
    continue_on_unexpected: false
    stage: prepare
    meta: "{}"
    generation_id: ""
    order: 1
    case_id: flexible_backup_setting_wait_cluster_active
    case_type: user_defined
    step_type: defined

  - operation_id: TidbService_GetBackupSetting
    request_type: http
    request: |-
      {
        "method": "GET",
        "path": "/tidbs/{tidbId}/backupSetting",
        "headers": {},
        "query_params": {},
        "body": {},
        "auth": {
          "auth_type": "digest",
          "content": {
            "private_key": "placeholder",
            "public_key": "placeholder"
          }
        },
        "path_params": {
          "tidbId": "cluster_1"
        }
      }
    expect: |-
      {
        "status_code": 200,
        "cel": "body.backupPolicy == 'TIER1' && body.mode == 'STANDARD_BUNDLE' && body.retentionDays == 7 && body.dailyBackupTimeUtc == '00:00'"
      }
    save: null
    description: "Verify the default standard bundle backup setting before switching to flexible retention."
    max_retries: 10
    delay_after: 30
    name: "get_default_backup_setting"
    continue_on_unexpected: false
    stage: execute
    meta: "{}"
    generation_id: ""
    order: 2
    case_id: flexible_backup_setting_get_default
    case_type: user_defined
    step_type: defined

  - operation_id: TidbService_UpdateBackupSetting
    request_type: http
    request: |-
      {
        "method": "PATCH",
        "path": "/tidbs/{tidbId}/backupSetting",
        "headers": {},
        "query_params": {},
        "body": {
          "mode": "FLEXIBLE_RETENTION",
          "retentionDays": 2,
          "dailyBackupTimeUtc": "{dailyBackupTimeUtc}"
        },
        "auth": {
          "auth_type": "digest",
          "content": {
            "private_key": "placeholder",
            "public_key": "placeholder"
          }
        },
        "path_params": {
          "tidbId": "cluster_1"
        },
        "body_params": {
          "dailyBackupTimeUtc": "flex_daily_backup_time_utc"
        }
      }
    expect: |-
      {
        "status_code": 400,
        "cel": ""
      }
    save: null
    description: "Verify flexible retention rejects retention days below the public minimum."
    max_retries: 0
    delay_after: 0
    name: "reject_too_short_flexible_retention"
    continue_on_unexpected: false
    stage: execute
    meta: "{}"
    generation_id: ""
    order: 2.5
    case_id: flexible_backup_setting_reject_too_short_retention
    case_type: user_defined
    step_type: defined

  - operation_id: TidbService_UpdateBackupSetting
    request_type: http
    request: |-
      {
        "method": "PATCH",
        "path": "/tidbs/{tidbId}/backupSetting",
        "headers": {},
        "query_params": {},
        "body": {
          "mode": "FLEXIBLE_RETENTION",
          "retentionDays": 34,
          "dailyBackupTimeUtc": "{dailyBackupTimeUtc}"
        },
        "auth": {
          "auth_type": "digest",
          "content": {
            "private_key": "placeholder",
            "public_key": "placeholder"
          }
        },
        "path_params": {
          "tidbId": "cluster_1"
        },
        "body_params": {
          "dailyBackupTimeUtc": "flex_daily_backup_time_utc"
        }
      }
    expect: |-
      {
        "status_code": 400,
        "cel": ""
      }
    save: null
    description: "Verify flexible retention rejects retention days above the public maximum."
    max_retries: 0
    delay_after: 0
    name: "reject_too_long_flexible_retention"
    continue_on_unexpected: false
    stage: execute
    meta: "{}"
    generation_id: ""
    order: 2.6
    case_id: flexible_backup_setting_reject_too_long_retention
    case_type: user_defined
    step_type: defined

  - operation_id: TidbService_UpdateBackupSetting
    request_type: http
    request: |-
      {
        "method": "PATCH",
        "path": "/tidbs/{tidbId}/backupSetting",
        "headers": {},
        "query_params": {},
        "body": {
          "mode": "FLEXIBLE_RETENTION",
          "retentionDays": 20,
          "dailyBackupTimeUtc": "{dailyBackupTimeUtc}"
        },
        "auth": {
          "auth_type": "digest",
          "content": {
            "private_key": "placeholder",
            "public_key": "placeholder"
          }
        },
        "path_params": {
          "tidbId": "cluster_1"
        },
        "body_params": {
          "dailyBackupTimeUtc": "flex_daily_backup_time_utc"
        }
      }
    expect: |-
      {
        "status_code": 200,
        "cel": "body.backupPolicy == 'TIER1' && body.mode == 'FLEXIBLE_RETENTION' && body.retentionDays == 20 && body.dailyBackupTimeUtc == '{flex_daily_backup_time_utc}'"
      }
    save: null
    description: "Switch backup setting to flexible retention through public NextGen OpenAPI. This should persist in global and synchronously call regional backup GC and auto backup metering updates."
    max_retries: 0
    delay_after: 0
    name: "update_backup_setting_to_flexible_retention"
    continue_on_unexpected: false
    stage: execute
    meta: "{}"
    generation_id: ""
    order: 3
    case_id: flexible_backup_setting_update_to_flexible
    case_type: user_defined
    step_type: defined

  - operation_id: TidbService_GetBackupSetting
    request_type: http
    request: |-
      {
        "method": "GET",
        "path": "/tidbs/{tidbId}/backupSetting",
        "headers": {},
        "query_params": {},
        "body": {},
        "auth": {
          "auth_type": "digest",
          "content": {
            "private_key": "placeholder",
            "public_key": "placeholder"
          }
        },
        "path_params": {
          "tidbId": "cluster_1"
        }
      }
    expect: |-
      {
        "status_code": 200,
        "cel": "body.backupPolicy == 'TIER1' && body.mode == 'FLEXIBLE_RETENTION' && body.retentionDays == 20 && body.dailyBackupTimeUtc == '{flex_daily_backup_time_utc}'"
      }
    save: null
    description: "Read back the flexible backup setting from global after the regional sync succeeds."
    max_retries: 5
    delay_after: 10
    name: "verify_flexible_backup_setting"
    continue_on_unexpected: false
    stage: execute
    meta: "{}"
    generation_id: ""
    order: 4
    case_id: flexible_backup_setting_verify_flexible
    case_type: user_defined
    step_type: defined

  - operation_id: TidbService_UpdateBackupSetting
    request_type: http
    request: |-
      {
        "method": "PATCH",
        "path": "/tidbs/{tidbId}/backupSetting",
        "headers": {},
        "query_params": {},
        "body": {
          "mode": "FLEXIBLE_RETENTION",
          "retentionDays": 3,
          "dailyBackupTimeUtc": "{dailyBackupTimeUtc}"
        },
        "auth": {
          "auth_type": "digest",
          "content": {
            "private_key": "placeholder",
            "public_key": "placeholder"
          }
        },
        "path_params": {
          "tidbId": "cluster_1"
        },
        "body_params": {
          "dailyBackupTimeUtc": "flex_daily_backup_time_utc"
        }
      }
    expect: |-
      {
        "status_code": 200,
        "cel": "body.backupPolicy == 'TIER1' && body.mode == 'FLEXIBLE_RETENTION' && body.retentionDays == 3 && body.dailyBackupTimeUtc == '{flex_daily_backup_time_utc}'"
      }
    save: null
    description: "Shorten flexible retention through the public API and verify the updated setting is accepted."
    max_retries: 0
    delay_after: 0
    name: "shorten_flexible_retention"
    continue_on_unexpected: false
    stage: execute
    meta: "{}"
    generation_id: ""
    order: 4.5
    case_id: flexible_backup_setting_shorten_retention
    case_type: user_defined
    step_type: defined

  - operation_id: TidbService_GetBackupSetting
    request_type: http
    request: |-
      {
        "method": "GET",
        "path": "/tidbs/{tidbId}/backupSetting",
        "headers": {},
        "query_params": {},
        "body": {},
        "auth": {
          "auth_type": "digest",
          "content": {
            "private_key": "placeholder",
            "public_key": "placeholder"
          }
        },
        "path_params": {
          "tidbId": "cluster_1"
        }
      }
    expect: |-
      {
        "status_code": 200,
        "cel": "body.backupPolicy == 'TIER1' && body.mode == 'FLEXIBLE_RETENTION' && body.retentionDays == 3 && body.dailyBackupTimeUtc == '{flex_daily_backup_time_utc}'"
      }
    save: null
    description: "Read back the shortened flexible retention setting before waiting for a flexible backup."
    max_retries: 5
    delay_after: 10
    name: "verify_shortened_flexible_retention"
    continue_on_unexpected: false
    stage: execute
    meta: "{}"
    generation_id: ""
    order: 4.6
    case_id: flexible_backup_setting_verify_shortened_retention
    case_type: user_defined
    step_type: defined

  - operation_id: TidbService_ListTidbBackups
    request_type: http
    request: |-
      {
        "method": "GET",
        "path": "/tidbs/{tidbId}/backups",
        "headers": {},
        "query_params": {},
        "body": {},
        "auth": {
          "auth_type": "digest",
          "content": {
            "private_key": "placeholder",
            "public_key": "placeholder"
          }
        },
        "path_params": {
          "tidbId": "cluster_1"
        }
      }
    expect: |-
      {
        "status_code": 200,
        "cel": "body.backups[0].id != '' && body.backups[0].state == 'SUCCEEDED'"
      }
    save: |-
      {
        "placeholder": [
          {
            "key": "backup_1",
            "eval": "body.backups[0].id"
          }
        ]
      }
    description: "Wait until a successful automatic backup is available after switching to flexible retention."
    max_retries: 70
    delay_after: 60
    name: "wait_flexible_auto_backup_succeeded"
    continue_on_unexpected: false
    stage: execute
    meta: "{}"
    generation_id: ""
    order: 5
    case_id: flexible_backup_setting_wait_flexible_auto_backup
    case_type: user_defined
    step_type: defined

  - operation_id: TidbService_DeleteTidbBackup
    request_type: http
    request: |-
      {
        "method": "DELETE",
        "path": "/tidbs/{tidbId}/backups/{backupId}",
        "headers": {},
        "query_params": {},
        "body": {},
        "auth": {
          "auth_type": "digest",
          "content": {
            "private_key": "placeholder",
            "public_key": "placeholder"
          }
        },
        "path_params": {
          "tidbId": "cluster_1",
          "backupId": "backup_1"
        }
      }
    expect: |-
      {
        "status_code": 400,
        "cel": "body.message == 'This backup is protected under the Data Safety Policy and cannot be deleted until expiration. Contact support if you want to delete it before it expires.'"
      }
    save: null
    description: "Verify Data Safety Policy prevents deleting the latest successful automatic backup before expiration."
    max_retries: 0
    delay_after: 0
    name: "reject_delete_latest_flexible_auto_backup"
    continue_on_unexpected: false
    stage: execute
    meta: "{}"
    generation_id: ""
    order: 6
    case_id: flexible_backup_setting_reject_delete_latest_auto_backup
    case_type: user_defined
    step_type: defined

  - operation_id: TidbService_RestoreTidb
    request_type: http
    request: |-
      {
        "method": "POST",
        "path": "/tidbs:restore",
        "headers": {},
        "query_params": {},
        "body": {
          "tidb": {
            "displayName": "sce-ng-flexible-backup-restore",
            "regionId": "{regionId}",
            "minRcu": "5000",
            "maxRcu": "5500",
            "servicePlan": "Premium"
          },
          "sourceTidbId": "{tidbId}",
          "restoreMode": "SNAPSHOT",
          "backupId": "{backupId}"
        },
        "auth": {
          "auth_type": "digest",
          "content": {
            "private_key": "placeholder",
            "public_key": "placeholder"
          }
        },
        "body_params": {
          "regionId": "region_id",
          "tidbId": "cluster_1",
          "backupId": "backup_1"
        }
      }
    expect: |-
      {
        "status_code": 200,
        "cel": ""
      }
    save: |-
      {
        "placeholder": [
          {
            "key": "cluster_2",
            "eval": "body.tidb.tidbId"
          }
        ]
      }
    description: "Restore a new Premium cluster from the automatic backup produced under flexible retention."
    max_retries: 0
    delay_after: 0
    name: "restore_from_flexible_auto_backup"
    continue_on_unexpected: false
    stage: execute
    meta: "{}"
    generation_id: ""
    order: 7
    case_id: flexible_backup_setting_restore_from_flexible_backup
    case_type: user_defined
    step_type: defined

  - operation_id: TidbService_RestoreStatus
    request_type: http
    request: |-
      {
        "method": "GET",
        "path": "/tidbs/{tidbId}:restoreStatus",
        "headers": {},
        "query_params": {},
        "body": {},
        "auth": {
          "auth_type": "digest",
          "content": {
            "private_key": "placeholder",
            "public_key": "placeholder"
          }
        },
        "path_params": {
          "tidbId": "cluster_2"
        }
      }
    expect: |-
      {
        "status_code": 200,
        "cel": "body.state == 'SUCCEEDED'"
      }
    save: null
    description: "Wait until the restore from flexible automatic backup succeeds."
    max_retries: 120
    delay_after: 30
    name: "wait_flexible_backup_restore_succeeded"
    continue_on_unexpected: false
    stage: execute
    meta: "{}"
    generation_id: ""
    order: 8
    case_id: flexible_backup_setting_wait_restore_succeeded
    case_type: user_defined
    step_type: defined

  - operation_id: TidbService_GetTidb
    request_type: http
    request: |-
      {
        "method": "GET",
        "path": "/tidbs/{tidbId}",
        "headers": {},
        "query_params": {},
        "body": {},
        "auth": {
          "auth_type": "digest",
          "content": {
            "private_key": "placeholder",
            "public_key": "placeholder"
          }
        },
        "path_params": {
          "tidbId": "cluster_2"
        }
      }
    expect: |-
      {
        "status_code": 200,
        "cel": "body.state == 'ACTIVE' && body.minRcu == '5000' && body.maxRcu == '5500'"
      }
    save: null
    description: "Verify the restored cluster becomes ACTIVE."
    max_retries: 120
    delay_after: 30
    name: "wait_restored_cluster_active"
    continue_on_unexpected: false
    stage: execute
    meta: "{}"
    generation_id: ""
    order: 9
    case_id: flexible_backup_setting_wait_restored_cluster_active
    case_type: user_defined
    step_type: defined

  - operation_id: TidbService_DeleteTidb
    request_type: http
    request: |-
      {
        "method": "DELETE",
        "path": "/tidbs/{tidbId}",
        "headers": {},
        "query_params": {},
        "body": {},
        "auth": {
          "auth_type": "digest",
          "content": {
            "private_key": "placeholder",
            "public_key": "placeholder"
          }
        },
        "path_params": {
          "tidbId": "cluster_1"
        }
      }
    expect: |-
      {
        "status_code": 200,
        "cel": ""
      }
    save: null
    description: "Delete the source cluster while it is still using flexible retention."
    max_retries: 0
    delay_after: 0
    name: "delete_flexible_source_cluster"
    continue_on_unexpected: false
    stage: cleanup
    meta: "{}"
    generation_id: ""
    order: 10
    case_id: flexible_backup_setting_delete_source_cluster
    case_type: user_defined
    step_type: defined

  - operation_id: BackupService_ListDeletedTidbs
    request_type: http
    request: |-
      {
        "method": "GET",
        "path": "/backups:listDeletedTidbs?orgId={orgId}&tidbIds[]={tidbId}",
        "path_params": {
          "tidbId": "cluster_1",
          "orgId": "org_id"
        },
        "headers": {},
        "query_params": {},
        "body": {},
        "auth": {
          "auth_type": "digest",
          "content": {
            "private_key": "placeholder",
            "public_key": "placeholder"
          }
        }
      }
    expect: |-
      {
        "status_code": 200,
        "cel": "body.totalSize > 0"
      }
    save: null
    description: "Verify the deleted source cluster remains visible in Archived Backups / Recycle Bin while its flexible-retention backup is protected."
    max_retries: 120
    delay_after: 30
    name: "verify_deleted_flexible_cluster_archived_backup"
    continue_on_unexpected: false
    stage: cleanup
    meta: "{}"
    generation_id: ""
    order: 11
    case_id: flexible_backup_setting_verify_deleted_cluster_archived_backup
    case_type: user_defined
    step_type: defined

  - operation_id: TidbService_DeleteRestoreTidb
    request_type: http
    request: |-
      {
        "method": "DELETE",
        "path": "/tidbs/{tidbId}",
        "headers": {},
        "query_params": {},
        "body": {},
        "auth": {
          "auth_type": "digest",
          "content": {
            "private_key": "placeholder",
            "public_key": "placeholder"
          }
        },
        "path_params": {
          "tidbId": "cluster_2"
        }
      }
    expect: |-
      {
        "status_code": 200,
        "cel": ""
      }
    save: null
    description: "Clean up the restored cluster."
    max_retries: 0
    delay_after: 0
    name: "delete_restored_cluster"
    continue_on_unexpected: false
    stage: cleanup
    meta: "{}"
    generation_id: ""
    order: 12
    case_id: flexible_backup_setting_delete_restored_cluster
    case_type: user_defined
    step_type: defined
