Skip to content

Commit

Permalink
add option to insert new rows at the top of the sheets
Browse files Browse the repository at this point in the history
use append to add rows at the bottom of the sheet to fix race conditions on concurrent updates
  • Loading branch information
alanb-sony committed Apr 27, 2020
1 parent 5581e17 commit 3b76b29
Showing 1 changed file with 59 additions and 26 deletions.
85 changes: 59 additions & 26 deletions utilities/run-test-suites/gsheetsImport/resultsImporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,44 @@ def ranges_equal(first, second):
return True


def gsheets_import(test_results, worksheet, filename, start_col=1):
def insert_row(worksheet, data, row):
data_values = [{
"userEnteredValue": ({"formulaValue": x} if x.startswith("=") else {"stringValue": x})
} for x in data]
worksheet.spreadsheet.batch_update({
'requests': [{
'insertDimension': {
'range': {
'sheetId': worksheet.id,
'dimension': 'ROWS',
'startIndex': row,
'endIndex': row + 1
},
"inheritFromBefore": False
}
}, {
'updateCells': {
'start': {
'sheetId': worksheet.id,
'rowIndex': row,
'columnIndex': 0,
},
'rows': [
{
"values": data_values
}
],
'fields': "userEnteredValue"
}
}]
})


def gsheets_import(test_results, worksheet, filename, start_col=1, insert=False):
"""Upload results data to spreadsheet"""

worksheet_data = worksheet.get_all_values()
populated_rows = len(worksheet_data)
if populated_rows == 0:
# Blank spreadsheet, row 1 will be for column titles
current_row = 2
else:
current_row = populated_rows+1

# Columns before start_col reserved for manually entered details
start_col = max(1, start_col)

Expand All @@ -86,50 +113,50 @@ def gsheets_import(test_results, worksheet, filename, start_col=1):
original_cell_list_names = copy.deepcopy(cell_list_names)

# Results
cell_list_results = get_range(worksheet_data, current_row, 1, current_row, next_col)
cell_list_results = [""] * len(cell_list_names)

# Columns for Filename, URLs Tested, Timestamp, Test Suite
current_index = start_col-1 # list is 0-indexed whereas rows/cols are 1-indexed
cell_list_names[current_index].value = "Filename"
cell_list_results[current_index].value = filename
cell_list_results[current_index] = filename
current_index += 1
cell_list_names[current_index].value = "URLs Tested"
try:
urls_tested = []
for endpoint in test_results["endpoints"]:
urls_tested.append("{}:{} ({})".format(endpoint["host"], endpoint["port"], endpoint["version"]))
cell_list_results[current_index].value = ", ".join(urls_tested)
cell_list_results[current_index] = ", ".join(urls_tested)
except Exception:
print(" * WARNING: JSON file does not include endpoints")
cell_list_results[current_index].value = test_results["url"]
cell_list_results[current_index] = test_results["url"]
current_index += 1
cell_list_names[current_index].value = "Timestamp"
cell_list_results[current_index].value = (datetime.datetime.utcfromtimestamp(test_results["timestamp"])
.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + 'Z')
cell_list_results[current_index] = (datetime.datetime.utcfromtimestamp(test_results["timestamp"])
.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + 'Z')
current_index += 1
cell_list_names[current_index].value = "Test Suite"
try:
cell_list_results[current_index].value = "{} ({})".format(test_results["suite"],
test_results["config"]["VERSION"])
cell_list_results[current_index] = "{} ({})".format(test_results["suite"],
test_results["config"]["VERSION"])
except Exception:
print(" * WARNING: JSON file does not include test suite version")
cell_list_results[current_index].value = test_results["suite"]
cell_list_results[current_index] = test_results["suite"]

# Columns for counts of Tests and each Test Status
results_addr = "{}:{}".format(gspread.utils.rowcol_to_a1(current_row, results_col),
gspread.utils.rowcol_to_a1(current_row, 1)[1:])
result_col_name = gspread.utils.rowcol_to_a1(1, results_col)[0:-1]
results_addr = 'INDIRECT("{}"&ROW()&":"&ROW())'.format(result_col_name)

current_index += 1
cell_list_names[current_index].value = "Tests"
# count non-empty cells on rest of this row
cell_list_results[current_index].value = "=COUNTIF({}, \"?*\")".format(results_addr)
cell_list_results[current_index] = "=COUNTIF({}, \"?*\")".format(results_addr)
for state in TEST_STATES:
current_index += 1
cell_list_names[current_index].value = state
# count cells on the rest of this row that match this column's status
current_col_addr = gspread.utils.rowcol_to_a1(1, cell_list_names[current_index].col)
cell_list_results[current_index].value = "=COUNTIF({}, CONCAT({},\"*\"))" \
.format(results_addr, current_col_addr)
cell_list_results[current_index] = "=COUNTIF({}, CONCAT({},\"*\"))" \
.format(results_addr, current_col_addr)

# Columns for the Results
for result in test_results["results"]:
Expand All @@ -139,17 +166,22 @@ def gsheets_import(test_results, worksheet, filename, start_col=1):
col = next((cell.col for cell in cell_list_names if cell.value == result["name"]), None)
if col:
index = col-1 # list is 0-indexed whereas rows/cols are 1-indexed
cell_list_results[index].value = cell_contents
cell_list_results[index] = cell_contents
else:
# Test name not found, append column (since gspread doesn't make it easy to insert one)
col = cell_list_names[-1].col+1 # = cell_list_results[-1].col+1
cell_list_names.append(gspread.Cell(1, col, result["name"]))
cell_list_results.append(gspread.Cell(current_row, col, cell_contents))
cell_list_results.append(cell_contents)

if not ranges_equal(original_cell_list_names, cell_list_names):
worksheet.update_cells(cell_list_names)
# 'USER_ENTERED' allows formulae to be used
worksheet.update_cells(cell_list_results, value_input_option='USER_ENTERED')
if insert:
insert_row(worksheet, cell_list_results, 1)
else:
worksheet.append_rows([cell_list_results],
value_input_option='USER_ENTERED',
insert_data_option='INSERT_ROWS',
table_range="A1")


def main():
Expand All @@ -158,6 +190,7 @@ def main():
parser.add_argument("--sheet", required=True)
parser.add_argument("--credentials", default="credentials.json")
parser.add_argument("--start_col", default="1", type=int)
parser.add_argument("--insert", action="store_true")
args = parser.parse_args()

credentials = ServiceAccountCredentials.from_json_keyfile_name(args.credentials, SCOPES)
Expand All @@ -178,7 +211,7 @@ def main():
# could add_worksheet?
sys.exit(1)

gsheets_import(test_results, worksheet, json_file_name, args.start_col)
gsheets_import(test_results, worksheet, json_file_name, args.start_col, args.insert)


if __name__ == '__main__':
Expand Down

0 comments on commit 3b76b29

Please sign in to comment.