Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data tests can cause "user query limit" issue if queries queue for over 600 seconds. #673

Merged
merged 2 commits into from
Jan 3, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 37 additions & 33 deletions spectacles/validators/data_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from spectacles.lookml import Explore, Project
from spectacles.exceptions import SpectaclesException, DataTestError

QUERY_SLOT_LIMIT = 15 # This is the per-user query limit in Looker for most instances


@dataclass
class DataTest:
Expand Down Expand Up @@ -93,40 +95,42 @@ async def get_tests(self, project: Project) -> List[DataTest]:

async def validate(self, tests: List[DataTest]) -> List[DataTestError]:
data_test_errors: List[DataTestError] = []
query_slot = asyncio.Semaphore(QUERY_SLOT_LIMIT)

async def run_test(test: DataTest) -> None:
results = await self.client.run_lookml_test(
test.project_name, model=test.explore.model_name, test=test.name
)
test.explore.queried = True
result = results[0] # For a single test, list with length 1

if result["success"]:
test.passed = True
test.explore.successes.append(
{
"model": test.explore.model_name,
"explore": test.explore.name,
"metadata": {
"test_name": result["test_name"],
"lookml_url": test.lookml_url,
"explore_url": test.explore_url,
},
}
async def run_test(test: DataTest, query_slot: asyncio.Semaphore) -> None:
async with query_slot:
results = await self.client.run_lookml_test(
test.project_name, model=test.explore.model_name, test=test.name
)
else:
test.passed = False
for error in result["errors"]:
error = DataTestError(
model=error["model_id"],
explore=error["explore"],
message=error["message"],
test_name=result["test_name"],
lookml_url=test.lookml_url,
explore_url=test.explore_url,
test.explore.queried = True
result = results[0] # For a single test, list with length 1

if result["success"]:
test.passed = True
test.explore.successes.append(
{
"model": test.explore.model_name,
"explore": test.explore.name,
"metadata": {
"test_name": result["test_name"],
"lookml_url": test.lookml_url,
"explore_url": test.explore_url,
},
}
)
data_test_errors.append(error)
test.explore.errors.append(error)

await asyncio.gather(*(run_test(test) for test in tests))
else:
test.passed = False
for error in result["errors"]:
error = DataTestError(
model=error["model_id"],
explore=error["explore"],
message=error["message"],
test_name=result["test_name"],
lookml_url=test.lookml_url,
explore_url=test.explore_url,
)
data_test_errors.append(error)
test.explore.errors.append(error)

await asyncio.gather(*(run_test(test, query_slot) for test in tests))
return data_test_errors