18896 Replace STORAGE_BACKEND with STORAGES and support Script running from S3 (#18680)

This commit is contained in:
Arthur Hanson
2025-03-17 07:36:34 -07:00
committed by GitHub
parent ffe035567a
commit 1b4e00aeda
14 changed files with 246 additions and 77 deletions

View File

@@ -2,10 +2,12 @@ import inspect
import json
import logging
import os
import re
import yaml
from django import forms
from django.conf import settings
from django.core.files.storage import storages
from django.core.validators import RegexValidator
from django.utils import timezone
from django.utils.functional import classproperty
@@ -367,9 +369,46 @@ class BaseScript:
def filename(self):
return inspect.getfile(self.__class__)
def findsource(self, object):
storage = storages.create_storage(storages.backends["scripts"])
with storage.open(os.path.basename(self.filename), 'r') as f:
data = f.read()
# Break the source code into lines
lines = [line + '\n' for line in data.splitlines()]
# Find the class definition
name = object.__name__
pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
# use the class definition with the least indentation
candidates = []
for i in range(len(lines)):
match = pat.match(lines[i])
if match:
if lines[i][0] == 'c':
return lines, i
candidates.append((match.group(1), i))
if not candidates:
raise OSError('could not find class definition')
# Sort the candidates by whitespace, and by line number
candidates.sort()
return lines, candidates[0][1]
@property
def source(self):
return inspect.getsource(self.__class__)
# Can't use inspect.getsource() as it uses os to get the file
# inspect uses ast, but that is overkill for this as we only do
# classes.
object = self.__class__
try:
lines, lnum = self.findsource(object)
lines = inspect.getblock(lines[lnum:])
return ''.join(lines)
except OSError:
return ''
@classmethod
def _get_vars(cls):
@@ -524,7 +563,12 @@ class BaseScript:
def load_yaml(self, filename):
"""
Return data from a YAML file
TODO: DEPRECATED: Remove this method in v4.4
"""
self._log(
_("load_yaml is deprecated and will be removed in v4.4"),
level=LogLevelChoices.LOG_WARNING
)
try:
from yaml import CLoader as Loader
except ImportError:
@@ -539,7 +583,12 @@ class BaseScript:
def load_json(self, filename):
"""
Return data from a JSON file
TODO: DEPRECATED: Remove this method in v4.4
"""
self._log(
_("load_json is deprecated and will be removed in v4.4"),
level=LogLevelChoices.LOG_WARNING
)
file_path = os.path.join(settings.SCRIPTS_ROOT, filename)
with open(file_path, 'r') as datafile:
data = json.load(datafile)
@@ -555,7 +604,6 @@ class BaseScript:
Run the report and save its results. Each test method will be executed in order.
"""
self.logger.info("Running report")
try:
for test_name in self.tests:
self._current_test = test_name