Quantify test pass/failures
Contents
Quantify test pass/failures#
In this notebook, the key perfomance indicators that we would like to create greater visbility into and track over time is the percent of tests that passed/failed. This can help track and measure the effectiveness and success of our testing process.
By measuring this metric, we can observe the trend of test failures over time and a decrease in the percent of failures over time (or increase in percent of test passes), should correlate to improved test efficiencies, enhanced testing process and error free releases. In this notebook, we derive the following metrics from the TestGrid dataset:
total number of test cases
number of test cases passed
number of test cases failed
percent of tests that pass
percent of tests that fail
Linked Issue: issue 1
## Import libraries
import gzip
import json
import os
import pandas as pd
import datetime
from ipynb.fs.defs.metric_template import (
testgrid_labelwise_encoding,
CephCommunication,
save_to_disk,
read_from_disk,
)
from dotenv import load_dotenv, find_dotenv
load_dotenv(find_dotenv())
True
## Specify variables
METRIC_NAME = "test_pass_failures"
# Specify the path for input grid data
INPUT_DATA_PATH = "../../../../data/raw/testgrid_183.json.gz"
# Specify the path for output metric data
OUTPUT_DATA_PATH = f"../../../../data/processed/metrics/{METRIC_NAME}"
## CEPH Bucket variables
## Create a .env file on your local with the correct configs
s3_endpoint_url = os.getenv("S3_ENDPOINT")
s3_access_key = os.getenv("S3_ACCESS_KEY")
s3_secret_key = os.getenv("S3_SECRET_KEY")
s3_bucket = os.getenv("S3_BUCKET")
s3_path = os.getenv("S3_PROJECT_KEY", "ai4ci/testgrid/metrics")
s3_input_data_path = "raw_data"
# Specify whether or not we are running this as a notebook or part of an automation pipeline.
AUTOMATION = os.getenv("IN_AUTOMATION")
## Import data
timestamp = datetime.datetime.today()
if AUTOMATION:
filename = f"testgrid_{timestamp.day}{timestamp.month}.json"
cc = CephCommunication(s3_endpoint_url, s3_access_key, s3_secret_key, s3_bucket)
s3_object = cc.s3_resource.Object(s3_bucket, f"{s3_input_data_path}/{filename}")
file_content = s3_object.get()["Body"].read().decode("utf-8")
testgrid_data = json.loads(file_content)
else:
with gzip.open(INPUT_DATA_PATH, "rb") as read_file:
testgrid_data = json.load(read_file)
Metric Calculation#
We find all the tests which are failing i.e. have a status code of 12
failures_list = testgrid_labelwise_encoding(testgrid_data, 12)
len(failures_list)
27192485
# Convert to dataframe
failures_df = pd.DataFrame(
failures_list,
columns=["timestamp", "tab", "grid", "test", "test_duration", "failure"],
)
failures_df = failures_df.drop(columns="test_duration")
failures_df.head()
timestamp | tab | grid | test | failure | |
---|---|---|---|---|---|
0 | 2021-03-15 23:40:20 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | False |
1 | 2021-03-15 00:01:06 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | False |
2 | 2021-03-13 20:51:32 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | False |
3 | 2021-03-13 07:51:20 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | False |
4 | 2021-03-13 06:43:20 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | False |
We now find all the tests which are passing i.e. have a status code of 1
passing_list = testgrid_labelwise_encoding(testgrid_data, 1)
len(passing_list)
27192485
# Convert to dataframe
passing_df = pd.DataFrame(
passing_list,
columns=["timestamp", "tab", "grid", "test", "test_duration", "passing"],
)
passing_df = passing_df.drop(columns="test_duration")
passing_df.head()
timestamp | tab | grid | test | passing | |
---|---|---|---|---|---|
0 | 2021-03-15 23:40:20 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | True |
1 | 2021-03-15 00:01:06 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | True |
2 | 2021-03-13 20:51:32 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | True |
3 | 2021-03-13 07:51:20 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | True |
4 | 2021-03-13 06:43:20 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | True |
combined_df = pd.merge(
failures_df,
passing_df,
on=["timestamp", "tab", "grid", "test"],
)
combined_df.head()
timestamp | tab | grid | test | failure | passing | |
---|---|---|---|---|---|---|
0 | 2021-03-15 23:40:20 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | False | True |
1 | 2021-03-15 00:01:06 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | False | True |
2 | 2021-03-13 20:51:32 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | False | True |
3 | 2021-03-13 07:51:20 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | False | True |
4 | 2021-03-13 06:43:20 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | False | True |
## The following implements test pass/failure percentage metrics
## Moving forward, this will be aggregated in Superset
## For the sake of completeness, it is implmented here
no_tests = combined_df.test.count()
print("Total number of tests: %i" % (no_tests))
no_failures = combined_df.failure.sum()
print("Total number of failing tests: %i" % (no_failures))
test_failures_percentage = (
(combined_df.failure.sum() / combined_df.test.count())
) * 100
print("Test failure percentage: %f" % (test_failures_percentage))
no_pass = combined_df.passing.sum()
print("Total number of passing tests: %i" % (no_pass))
test_pass_percentage = ((combined_df.passing.sum() / combined_df.passing.count())) * 100
print("Test pass percentage: %f" % (test_pass_percentage))
Total number of tests: 27219757
Total number of failing tests: 200541
Test failure percentage: 0.736748
Total number of passing tests: 14281659
Test pass percentage: 52.467989
Save results to Ceph or locally#
Use the following helper function to save the data frame in a parquet format on the Ceph bucket if we are running in automation, and locally if not.
timestamp = datetime.datetime.now()
if AUTOMATION:
cc = CephCommunication(s3_endpoint_url, s3_access_key, s3_secret_key, s3_bucket)
cc.upload_to_ceph(
combined_df.head(1000000),
s3_path,
f"{METRIC_NAME}/{METRIC_NAME}-{timestamp.year}-{timestamp.month}-{timestamp.day}.parquet",
)
else:
save_to_disk(
combined_df.head(1000000),
OUTPUT_DATA_PATH,
f"{METRIC_NAME}-{timestamp.year}-{timestamp.month}-{timestamp.day}.parquet",
)
## Sanity check to see if the dataset is the same
if AUTOMATION:
sanity_check = cc.read_from_ceph(
s3_path,
f"{METRIC_NAME}/{METRIC_NAME}-{timestamp.year}-{timestamp.month}-{timestamp.day}.parquet",
)
else:
sanity_check = read_from_disk(
OUTPUT_DATA_PATH,
f"{METRIC_NAME}-{timestamp.year}-{timestamp.month}-{timestamp.day}.parquet",
)
sanity_check
timestamp | tab | grid | test | failure | passing | |
---|---|---|---|---|---|---|
0 | 2021-03-15 23:40:20 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | False | True |
1 | 2021-03-15 00:01:06 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | False | True |
2 | 2021-03-13 20:51:32 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | False | True |
3 | 2021-03-13 07:51:20 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | False | True |
4 | 2021-03-13 06:43:20 | "redhat-assisted-installer" | periodic-ci-openshift-release-master-nightly-4... | Overall | False | True |
... | ... | ... | ... | ... | ... | ... |
999995 | 2021-03-12 11:16:51 | "redhat-openshift-informing" | release-openshift-origin-installer-launch-gcp | openshift-tests.[sig-network] NetworkPolicy [L... | False | False |
999996 | 2021-03-12 11:16:36 | "redhat-openshift-informing" | release-openshift-origin-installer-launch-gcp | openshift-tests.[sig-network] NetworkPolicy [L... | False | False |
999997 | 2021-03-12 11:08:17 | "redhat-openshift-informing" | release-openshift-origin-installer-launch-gcp | openshift-tests.[sig-network] NetworkPolicy [L... | False | False |
999998 | 2021-03-12 10:34:23 | "redhat-openshift-informing" | release-openshift-origin-installer-launch-gcp | openshift-tests.[sig-network] NetworkPolicy [L... | False | False |
999999 | 2021-03-12 10:30:18 | "redhat-openshift-informing" | release-openshift-origin-installer-launch-gcp | openshift-tests.[sig-network] NetworkPolicy [L... | False | False |
1000000 rows × 6 columns
Conclusion#
This notebook computed the number of test passes, test failures and test pass/failure percentage metric. The dataframe saved on ceph can be used to generate aggregated views and visualizations.