Compare commits

...
73 Commits
Author SHA1 Message Date
Andrew Ferlitsch 0688753f23 fix: remove pandas inmport 2023-05-05 15:24:49 +00:00
Andrew Ferlitsch 238c82b61f update: use util to read from bucket 2023-05-04 21:22:44 +00:00
Andrew Ferlitsch df79e810ff fix: revert to JSON 2023-05-04 21:02:44 +00:00
Andrew Ferlitsch 7831d443df update: NotbookExecutionResult updates 2023-05-04 18:08:36 +00:00
Andrew Ferlitsch a3d190a4a4 review: JSON simplifing 2023-05-04 17:49:25 +00:00
Andrew Ferlitsch f868bd6fbb review: JSON simplifing 2023-05-04 16:51:54 +00:00
Andrew Ferlitsch 72d89a826e fix: use json format 2023-05-03 19:42:08 +00:00
Andrew Ferlitsch f89b096643 fix: build_id required 2023-05-03 17:58:33 +00:00
Andrew Ferlitsch eee2b916f8 fix: review 2023-05-03 17:33:46 +00:00
Andrew Ferlitsch 0ba366f4cb fix: biz logic 2023-05-02 21:01:26 +00:00
Andrew Ferlitsch febb38f29d fix: biz logic 2023-05-02 20:50:08 +00:00
Andrew Ferlitsch f0e8e5ec61 fix: review 2023-05-01 21:56:43 +00:00
Andrew Ferlitsch d61d8e81cf fix: review 2023-05-01 20:13:01 +00:00
Andrew Ferlitsch 50abb8ac15 fix: review 2023-05-01 20:00:41 +00:00
Andrew Ferlitsch c08b27f30b fix: BUILD_ID 2023-05-01 19:53:46 +00:00
Andrew Ferlitsch cbd8688c00 fix: BUILD_ID 2023-05-01 18:24:38 +00:00
Andrew Ferlitsch a206e27a48 fix: BUILD_ID 2023-05-01 18:04:26 +00:00
Andrew Ferlitsch 290289cfb9 fix: BUILD_ID 2023-05-01 17:25:55 +00:00
Andrew Ferlitsch bcc4b57d78 fix: BUILD_ID 2023-05-01 17:03:17 +00:00
Andrew Ferlitsch 341674f08b fix: BUILD_ID 2023-05-01 16:35:25 +00:00
Andrew Ferlitsch c88efc023f fix: BUILD_ID 2023-05-01 16:07:56 +00:00
Andrew Ferlitsch a1954476b7 fix: flaky 2023-04-28 19:50:21 +00:00
Andrew Ferlitsch 2079f5281c debug: duration nit 2023-04-28 15:49:24 +00:00
Andrew Ferlitsch 2551d6dc51 debug: duration nit 2023-04-28 15:32:53 +00:00
Andrew Ferlitsch efe4d623c7 debug: casting 2023-04-28 14:15:54 +00:00
Andrew Ferlitsch 4b57466385 debug: casting 2023-04-28 04:24:11 +00:00
Andrew Ferlitsch 33de79d983 debug: casting 2023-04-28 04:03:42 +00:00
Andrew Ferlitsch 529a461b1b debug: casting 2023-04-28 03:21:04 +00:00
Andrew Ferlitsch 3c9c21c204 debug: accum 2023-04-28 00:45:39 +00:00
Andrew Ferlitsch bb69d6482c debug: accum 2023-04-28 00:09:07 +00:00
Andrew Ferlitsch d3ddcbf936 debug: accum 2023-04-27 23:26:39 +00:00
Andrew Ferlitsch fe8bdd2bb1 debug: accum 2023-04-27 23:07:41 +00:00
Andrew Ferlitsch 7c7e81e58a debug: accum 2023-04-27 22:04:28 +00:00
Andrew Ferlitsch 10c08c88c6 debug: accum 2023-04-27 21:45:31 +00:00
Andrew Ferlitsch 5b385a8517 debug: accum 2023-04-27 21:26:19 +00:00
Andrew Ferlitsch dca60a6d81 debug: indexer 2023-04-27 21:07:11 +00:00
Andrew Ferlitsch 4f636e4b66 debug: indxer 2023-04-27 20:36:08 +00:00
Andrew Ferlitsch 922cec34e9 debug: read csv 2023-04-27 20:12:02 +00:00
Andrew Ferlitsch 58f282c431 debug: read csv 2023-04-27 19:53:29 +00:00
Andrew Ferlitsch 92c05baa80 debug: read csv 2023-04-27 19:34:29 +00:00
Andrew Ferlitsch 3fc657a65b debug: read csv 2023-04-27 19:32:57 +00:00
Andrew FerlitschandGitHub 18c4d05fa7 Update requirements.txt 2023-04-27 12:10:27 -07:00
Andrew FerlitschandGitHub 7383d06d6b Update requirements.txt 2023-04-27 11:50:14 -07:00
Andrew Ferlitsch d490e7afec debug: load 2023-04-27 18:31:01 +00:00
Andrew Ferlitsch 991ce4a7bf debug: import issues 2023-04-27 17:34:05 +00:00
Andrew Ferlitsch 357442990b debug: pandas problem 2023-04-27 17:14:42 +00:00
Andrew Ferlitsch f6d3d87914 debug: matching notebook name 2023-04-27 16:52:52 +00:00
Andrew Ferlitsch ba426fd189 debug: not accumulating 2023-04-27 16:28:54 +00:00
Andrew Ferlitsch c483767f7d debug: not accumulating 2023-04-27 16:28:07 +00:00
Andrew Ferlitsch 2aee13899b debug: not accumulating 2023-04-27 16:27:17 +00:00
Andrew FerlitschandGitHub 1b2663a2a2 Update requirements.txt 2023-04-27 09:09:25 -07:00
Andrew Ferlitsch 724349332a debug: not accumulating 2023-04-27 15:50:33 +00:00
Andrew Ferlitsch 4dd7885518 debug: not accumulating 2023-04-27 15:08:41 +00:00
Andrew Ferlitsch 718b6438b5 debug: not accumulating 2023-04-27 14:11:48 +00:00
Andrew Ferlitsch 42436fc5f4 debug: not accumulating 2023-04-26 23:41:29 +00:00
Andrew Ferlitsch e80d660631 debug: no entries written 2023-04-26 23:22:07 +00:00
Andrew Ferlitsch 047959a82e debug: no entries written 2023-04-26 22:58:27 +00:00
Andrew Ferlitsch dee4822298 debug: bucket issue 2023-04-26 22:34:38 +00:00
Andrew Ferlitsch 73929c5681 debug: bucket issue 2023-04-26 22:14:40 +00:00
Andrew Ferlitsch 1bc349c40f debug: bucket issue 2023-04-26 21:54:27 +00:00
Andrew Ferlitsch b715c9063c debug: bucket issue 2023-04-26 20:59:16 +00:00
Andrew Ferlitsch d28c7941ab debug: bucket issue 2023-04-26 20:35:09 +00:00
Andrew Ferlitsch 018865c59b debug: bucket issue 2023-04-26 19:48:48 +00:00
Andrew Ferlitsch aff204e286 fix: 2nd try at bucket issue 2023-04-26 19:26:14 +00:00
Andrew Ferlitsch 6eb7ee259a fix: 2nd try at bucket issue 2023-04-26 19:04:26 +00:00
Andrew Ferlitsch 47b3d72158 fix: ci/cd test on openin artifacts bucket 2023-04-26 18:34:01 +00:00
Andrew Ferlitsch 1e8a5b581d fix: tuning args 2023-04-26 16:45:11 +00:00
Andrew Ferlitsch 9515375c49 fix: gs bucket ptrfix 2023-04-26 16:25:39 +00:00
Andrew Ferlitsch 6d23ea0423 fix: args for results file 2023-04-26 15:35:54 +00:00
Andrew Ferlitsch 1f9dbb5543 fix: use args for where to store results 2023-04-26 15:25:37 +00:00
Andrew Ferlitsch 63ebfa12ad update: accumulator support 2023-04-25 22:22:18 +00:00
Andrew Ferlitsch e57c8b8fcb fix: test percent 2023-04-25 18:22:51 +00:00
Andrew Ferlitsch df59b7400a update: record tallied results to GCS bucket 2023-04-25 17:59:05 +00:00
4 changed files with 123 additions and 12 deletions
+19 -4
View File
@@ -17,7 +17,7 @@
import argparse
import pathlib
import random
import os
import execute_changed_notebooks_helper
@@ -47,6 +47,12 @@ parser.add_argument(
required=False,
default=100,
)
parser.add_argument(
"--build_id",
type=str,
help="The build id (which may be a Cloud Build job specific or user explicit.",
required=True
)
parser.add_argument(
"--base_branch",
help="The base git branch to diff against to find changed files.",
@@ -129,26 +135,35 @@ changed_notebooks = execute_changed_notebooks_helper.get_changed_notebooks(
base_branch=args.base_branch,
)
results_bucket = f"{args.artifacts_bucket}"
results_file = f"{args.build_id}.json"
if args.test_percent == 100:
notebooks = changed_notebooks
accumulative_results = {}
else:
notebooks = [changed_notebook for changed_notebook in changed_notebooks if random.randint(1, 100) < args.test_percent]
accumulative_results = execute_changed_notebooks_helper.load_results(results_bucket, results_file)
notebooks = [changed_notebook for changed_notebook in changed_notebooks if execute_changed_notebooks_helper.select_notebook(changed_notebook, accumulative_results, args.test_percent)]
if args.dry_run:
print("Dry run ...\n")
for notebook in notebooks:
print(f"Would execute: {notebook.path}")
print(f"Would execute: {notebook}")
else:
execute_changed_notebooks_helper.process_and_execute_notebooks(
notebooks=notebooks,
container_uri=args.container_uri,
staging_bucket=args.staging_bucket,
artifacts_bucket=args.artifacts_bucket,
results_file=results_file,
accumulative_results=accumulative_results,
should_parallelize=args.should_parallelize,
timeout=args.timeout,
variable_project_id=args.variable_project_id,
variable_region=args.variable_region,
variable_service_account=args.variable_service_account,
variable_vpc_network=args.variable_vpc_network,
private_pool_id=args.private_pool_id,
private_pool_id=args.private_pool_id
)
@@ -21,11 +21,15 @@ import json
import git
import operator
import os
import io
import json
import pathlib
import re
import subprocess
import random
from google.cloud import storage
import utils
from typing import List, Optional
from typing import List, Optional, Dict, Any
from utils import util
import execute_notebook_helper
@@ -65,7 +69,9 @@ def format_timedelta(delta: datetime.timedelta) -> str:
@dataclasses.dataclass
class NotebookExecutionResult:
name: str
path: str
duration: datetime.timedelta
start_time: datetime.datetime
is_pass: bool
log_url: str
output_uri: str
@@ -80,6 +86,40 @@ class NotebookExecutionResult:
else:
return None
def load_results(results_bucket: str,
results_file: str) -> Dict[str,Any]:
'''
Load accumulated notebook test results
'''
print("Loading existing accumulative results ...")
accumulative_results = {}
try:
content = util.download_blob_into_memory(results_bucket, results_file, download_as_text=True)
accumulative_results = json.loads(content)
print(accumulative_results)
except Exception as e:
print(e)
# If there are no accumulative results, an empty dict is returned
return accumulative_results
def select_notebook(changed_notebook: str,
accumulative_results: Dict[str, Any],
test_percent: int) -> bool:
'''
Algorithm to randomly select a notebook, but weight the propbability of selected based on past failures
'''
if changed_notebook in accumulative_results:
pass_count = accumulative_results[changed_notebook]['passed']
fail_count = accumulative_results[changed_notebook]['failed']
else:
pass_count = 1
fail_count = 0
return (random.randint(1, 100) * (1 + (fail_count / (pass_count + fail_count))) < test_percent)
def _process_notebook(
notebook_path: str,
@@ -191,7 +231,9 @@ def process_and_execute_notebook(
result = NotebookExecutionResult(
name=tag,
path=notebook,
duration=datetime.timedelta(seconds=0),
start_time=datetime.datetime.now(),
is_pass=False,
output_uri=notebook_output_uri,
log_url="",
@@ -201,7 +243,6 @@ def process_and_execute_notebook(
)
# TODO: Handle cases where multiple notebooks have the same name
time_start = datetime.datetime.now()
operation = None
try:
# Get the python version for running the notebook if specified
@@ -247,9 +288,10 @@ def process_and_execute_notebook(
# Block and wait for the result
operation_result = operation.result(timeout=timeout_in_seconds)
result.duration = datetime.datetime.now() - time_start
result.duration = datetime.datetime.now() - result.start_time
result.is_pass = True
print(f"{notebook} PASSED in {format_timedelta(result.duration)}.")
except Exception as error:
result.error_message = str(error)
@@ -268,7 +310,7 @@ def process_and_execute_notebook(
except Exception as error:
result.error_message = str(error)
result.duration = datetime.datetime.now() - time_start
result.duration = datetime.datetime.now() - result.start_time
result.is_pass = False
print(
@@ -336,12 +378,54 @@ def get_changed_notebooks(
return notebooks
def _save_results(results: List[NotebookExecutionResult],
accumulative_results: Dict[str,Any],
artifacts_bucket: str,
results_file: str):
artifacts_bucket = artifacts_bucket.replace("gs://", "").split('/')[0]
print("Updating accumulative results ...")
for result in results:
if result.path in accumulative_results:
accumulative_results[result.path]['duration'] = result.duration.total_seconds()
accumulative_results[result.path]['start_time'] = str(result.start_time)
if result.is_pass:
accumulative_results[result.path]['passed'] += 1
else:
accumulative_results[result.path]['failed'] += 1
print(f"updating {result.path}")
else:
if result.is_pass:
pass_count = 1
fail_count = 0
else:
pass_count = 0
fail_count = 1
accumulative_results[result.path] = {
'duration': result.duration.total_seconds(),
'start_time': str(result.start_time),
'passed': pass_count,
'failed': fail_count
}
print(f"adding {result.path}")
print("Saving accumulative results ...")
content = json.dumps(accumulative_results)
client = storage.Client()
bucket = client.get_bucket(artifacts_bucket)
bucket.blob(str(results_file)).upload_from_string(content, 'text/json')
def process_and_execute_notebooks(
notebooks: List[str],
container_uri: str,
staging_bucket: str,
artifacts_bucket: str,
results_file: str,
accumulative_results: List[NotebookExecutionResult],
should_parallelize: bool,
timeout: int,
variable_project_id: str,
@@ -369,6 +453,10 @@ def process_and_execute_notebooks(
Required. The GCS staging bucket to write source code to.
artifacts_bucket (str):
Required. The GCS staging bucket to write executed notebooks to.
results_file (str):
Required: The path to the artifacts bucket to save results
accumulative_results (List):
Required: The in-memory previous accumulative notebook CI/CD test results.
variable_project_id (str):
Required. The value for PROJECT_ID to inject into notebooks.
variable_region (str):
@@ -471,7 +559,7 @@ def process_and_execute_notebooks(
print("=" * 100)
build_id = results_sorted[0].build_id
logs_bucket_name = (results_sorted[0].logs_bucket).removeprefix("gs://")
logs_bucket_name = (results_sorted[0].logs_bucket).replace("gs://", "")
log_file_name = f"log-{build_id}.txt"
log_contents = util.download_blob_into_memory(
@@ -489,6 +577,11 @@ def process_and_execute_notebooks(
else:
print(log_contents)
_save_results(results_sorted,
accumulative_results,
artifacts_bucket,
results_file)
print("\n=== END RESULTS===\n")
total_notebook_duration = functools.reduce(
@@ -36,7 +36,7 @@ steps:
- -c
- |
. workspace/env/bin/activate &&
python3 .cloud-build/execute_changed_notebooks_cli.py --test_paths_file "${_TEST_PATHS_FILE}" --base_branch "${_FORCED_BASE_BRANCH}" --container_uri ${_PYTHON_IMAGE} --staging_bucket ${_GCS_STAGING_BUCKET} --artifacts_bucket ${_GCS_STAGING_BUCKET}/executed_notebooks/PR_${_PR_NUMBER}/BUILD_${BUILD_ID} --variable_project_id ${PROJECT_ID} --variable_region ${_GCP_REGION} --variable_service_account ${_GCP_SERVICE_ACCOUNT} --variable_vpc_network "${_GPC_VPC_NETWORK_NAME}" `if [ ! -z "${_PRIVATE_POOL_NAME}" ]; then echo "--private_pool_id ${_PRIVATE_POOL_NAME}"; fi`
python3 .cloud-build/execute_changed_notebooks_cli.py --test_paths_file "${_TEST_PATHS_FILE}" --base_branch "${_FORCED_BASE_BRANCH}" --container_uri ${_PYTHON_IMAGE} --staging_bucket ${_GCS_STAGING_BUCKET} --artifacts_bucket ${_GCS_STAGING_BUCKET}/executed_notebooks/PR_${_PR_NUMBER}/BUILD_${BUILD_ID} --variable_project_id ${PROJECT_ID} --variable_region ${_GCP_REGION} --variable_service_account ${_GCP_SERVICE_ACCOUNT} --variable_vpc_network "${_GPC_VPC_NETWORK_NAME}" `if [ ! -z "${_PRIVATE_POOL_NAME}" ]; then echo "--private_pool_id ${_PRIVATE_POOL_NAME}"; fi` --build_id ${BUILD_ID}
env:
- 'IS_TESTING=1'
timeout: 86400s
+5 -2
View File
@@ -3,12 +3,15 @@ numpy
jupyter
nbconvert
papermill
pandas
matplotlib
tabulate
google-cloud-aiplatform
google-cloud-storage
google-cloud-build
google-cloud-storage
ratemate
GitPython
tqdm
tqdm
fsspec
pandas