Skip to content
1 change: 1 addition & 0 deletions scripts/live_test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
index.html
3 changes: 2 additions & 1 deletion scripts/live_test/CLITest.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Some content of this file is generated.

name: CLI TEST RUN $(USER_TARGET) $(USER_LIVE) $(Date:yyyyMMdd)$(Rev:.r)
name: CLI TEST RUN $(USER_TARGET) $(USER_LIVE) $(USER_USERNAME) $(Date:yyyyMMdd)$(Rev:.r)

trigger:
branches:
Expand Down Expand Up @@ -272,6 +272,7 @@ jobs:
commit_id=`git ls-remote https://github.com/Azure/azure-cli.git HEAD`
pip install sendgrid
pip install mysql-connector-python
pip install requests
# pip install certifi
# Send notification
az -v
Expand Down
10 changes: 10 additions & 0 deletions scripts/live_test/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,20 @@
Release History
===============

0.4.0
++++++

* Update pipeline run title.
* Generate index.html of testing results.
* Design a unique representation of a pipeline run.
* Make storage account container public.

0.3.0
++++++

* Support upgrading API version in pipeline.
* Fix a tiny DB bug.
* Fix pipe not close problem.

0.2.0
++++++
Expand Down
143 changes: 143 additions & 0 deletions scripts/live_test/generate_index.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

"""
Generate index.html of testing results HTML pages.
"""
import traceback
import os
import requests
import xml.etree.ElementTree as ET


def generate(container, container_url, testdata, USER_REPO, USER_BRANCH, COMMIT_ID, USER_LIVE):
"""
Generate index.html. Upload it to storage account
:param container:
:param container_url:
:return:
"""
data = []
url = container_url + '?restype=container&comp=list'
content = requests.get(url).content
# print(content)
root = ET.fromstring(content)
for blobs in root:
for blob in blobs:
name = url = ''
for e in blob:
if e.tag == 'Name':
name = e.text
if e.tag == 'Url':
url = e.text
if name == '' or url == '':
print('[Warning] Blob\'s name or url is empty, name: {}, url: {}'.format(name, url))
if name.endswith('.html'):
data.append({'name': name, 'url': url})
break
print(data)
html = render(data, container_url, testdata, USER_REPO, USER_BRANCH, COMMIT_ID, USER_LIVE)
with open('index.html', 'w') as f:
f.write(html)

# Upload to storage account
cmd = 'az storage blob upload -f index.html -c {} -n index.html --account-name clitestresultstac'.format(container)
print('Running: ' + cmd)
os.system(cmd)


def render(data, container_url, testdata, USER_REPO, USER_BRANCH, COMMIT_ID, USER_LIVE):
content = """
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about extract it to a seperate file?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

144 lines. Short file. Don't worry.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://jinja.palletsprojects.com/en/2.11.x/ is a good choice. But it costs more time to write code. The current content is simple. If it gets complex enough, we can use template engine.

<!DOCTYPE html>
<html>
<head>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
</head>
</style>
<body>
<h2>Testing results of Azure CLI</h2>
"""

live = 'True' if USER_LIVE == '--live' else 'False'

content += """
<p>
Repository: {}<br>
Branch: {}<br>
Commit: {}<br>
Live: {}<br>
</p>
""".format(USER_REPO, USER_BRANCH, COMMIT_ID, live)

content += """
<p>
<b>User Manual of Live Test Pipeline</b>
</p>
<p>
<a href=https://microsoft-my.sharepoint.com/:w:/p/fey/EZGC9LwrN3RAscVS5ylG4HMBX9h7W0ZSA7CDrhXN5Lvx6g?e=V8HUmd>Word</a>
</p>
"""

table = """
<p><b>Test results summary</b></p>
<table>
<tr>
<th>Module</th>
<th>Passed</th>
<th>Failed</th>
<th>Pass rate</th>
</tr>
"""

for module, passed, failed, rate in testdata.modules:
table += """
<tr>
<td>{}</td>
<td>{}</td>
<td>{}</td>
<td>{}</td>
</tr>
""".format(module, passed, failed, rate)

table += """
<tr>
<td>Total</td>
<td>{}</td>
<td>{}</td>
<td>{}</td>
</tr>
</table>
""".format(testdata.total[1], testdata.total[2], testdata.total[3])

content += table

content += """
<p><b>Reports</b></p>
"""

for item in data:
name = item['name']
url = item['url']
content += """
<a href={}>{}</a><br>
""".format(url, name)

content += """
</body>
</html>
"""
return content


if __name__ == '__main__':
url = 'https://clitestresultstac.blob.core.windows.net/20200919213646live'
try:
generate(url)
except:
traceback.print_exc()
76 changes: 41 additions & 35 deletions scripts/live_test/sendemail.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
import os
import traceback
import datetime
import random
import string
import test_data
import generate_index


SENDGRID_KEY = sys.argv[1]
Expand Down Expand Up @@ -58,6 +61,13 @@ def main():
except Exception:
print(traceback.format_exc())

# Generate index.html
try:
container_url = 'https://clitestresultstac.blob.core.windows.net/' + container
generate_index.generate(container, container_url, testdata, USER_REPO, USER_BRANCH, COMMIT_ID, USER_LIVE)
except Exception:
print(traceback.format_exc())

# Write database
try:
write_db(container, testdata)
Expand All @@ -69,22 +79,13 @@ def main():

def get_container_name():
"""
Generate container name in storage account
Generate container name in storage account. It is also an identifier of the pipeline run.
:return:
"""
print('Enter get_container_name()')

date = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
name = date
if USER_LIVE == '--live':
mode = 'live'
elif USER_LIVE == '':
mode = 'replay'
else:
mode = ''
name += mode
# if USER_TARGET == '' and USER_REPO == 'https://github.com/Azure/azure-cli.git' and USER_BRANCH == 'dev' and USER_LIVE == '--live':
# name += '_archive'
time = datetime.datetime.now().strftime('%Y%m%d-%H%M%S')
random_id = ''.join(random.choice(string.digits) for _ in range(6))
name = time + '-' + random_id
print('Exit get_container_name()')
return name

Expand All @@ -98,7 +99,7 @@ def upload_files(container):
print('Enter upload_files()')

# Create container
cmd = 'az storage container create -n {} --account-name clitestresultstac --account-key {}'
cmd = 'az storage container create -n {} --account-name clitestresultstac --account-key {} --public-access container'
os.popen(cmd.format(container, ACCOUNT_KEY))

# Upload files
Expand All @@ -109,7 +110,7 @@ def upload_files(container):
cmd = 'az storage blob upload -f {} -c {} -n {} --account-name clitestresultstac'
cmd = cmd.format(fullpath, container, name)
print('Running: ' + cmd)
os.popen(cmd)
os.system(cmd)

print('Exit upload_files()')

Expand All @@ -119,22 +120,25 @@ def write_db(container, testdata):
Insert data to database.
Sql statements to create table:
USE clidb;
CREATE TABLE t1 (
repo VARCHAR(200) COMMENT 'Repo URL',
branch VARCHAR(200) COMMENT 'Branch name',
commit VARCHAR(50) COMMENT 'Commit ID',
target VARCHAR(2000) COMMENT 'Target modules to test. Splited by space, Empty string represents all modules',
live TINYINT(1) COMMENT 'Live run or not',
user VARCHAR(50) COMMENT 'User (email address) who triggers the run',
pass INT COMMENT 'Number of passed tests',
fail INT COMMENT 'Number of failed tests',
rate VARCHAR(50) COMMENT 'Pass rate',
detail VARCHAR(10000) COMMENT 'Detail',
container VARCHAR(200) COMMENT 'Container URL',
date VARCHAR(10) COMMENT 'Date. E.g. 20200801',
time VARCHAR(10) COMMENT 'Time. E.g. 183000'
CREATE TABLE `t1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`repr` varchar(30) DEFAULT NULL COMMENT 'date_time_random6digits',
`repo` varchar(200) DEFAULT NULL COMMENT 'Repo URL',
`branch` varchar(200) DEFAULT NULL COMMENT 'Branch name',
`commit` varchar(50) DEFAULT NULL COMMENT 'Commit ID',
`target` varchar(2000) DEFAULT NULL COMMENT 'Target modules to test. Splited by space, Empty string represents all modules',
`live` tinyint(1) DEFAULT NULL COMMENT 'Live run or not',
`user` varchar(50) DEFAULT NULL COMMENT 'User (email address) who triggers the run',
`pass` int(11) DEFAULT NULL COMMENT 'Number of passed tests',
`fail` int(11) DEFAULT NULL COMMENT 'Number of failed tests',
`rate` varchar(50) DEFAULT NULL COMMENT 'Pass rate',
`detail` varchar(10000) DEFAULT NULL COMMENT 'Detail',
`container` varchar(200) DEFAULT NULL COMMENT 'Container URL',
`date` varchar(10) DEFAULT NULL COMMENT 'Date. E.g. 20200801',
`time` varchar(10) DEFAULT NULL COMMENT 'Time. E.g. 183000',
PRIMARY KEY (`id`),
UNIQUE KEY `repr` (`repr`)
);

"""
print('Enter write_db()')

Expand All @@ -146,22 +150,23 @@ def write_db(container, testdata):
host='clisqldbserver.mysql.database.azure.com',
database='clidb')
cursor = cnx.cursor()
sql = 'INSERT INTO t1 (repo, branch, commit, target, live, user, pass, fail, rate, detail, container, date, time) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s);'
sql = 'INSERT INTO t1 (repr, repo, branch, commit, target, live, user, pass, fail, rate, detail, container, date, time) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s);'
repr = container
repo = USER_REPO
branch = USER_BRANCH
commit = COMMIT_ID
target = USER_TARGET
live = 1 if USER_LIVE == '--live' else 0
user = REQUESTED_FOR_EMAIL
pass0 = testdata.total[2]
fail = testdata.total[1]
pass0 = testdata.total[1]
fail = testdata.total[2]
rate = testdata.total[3]
detail = str(testdata.modules)
container = 'https://clitestresultstac.blob.core.windows.net/' + container
container = 'https://clitestresultstac.blob.core.windows.net/{}/index.html'.format(container)
d = datetime.datetime.now()
date = d.strftime('%Y%m%d')
time = d.strftime('%H%M%S')
data = (repo, branch, commit, target, live, user, pass0, fail, rate, detail, container, date, time)
data = (repr, repo, branch, commit, target, live, user, pass0, fail, rate, detail, container, date, time)
print(data)
cursor.execute(sql, data)

Expand Down Expand Up @@ -205,6 +210,7 @@ def send_email(container, testdata):
data['personalizations'][0]['to'].append({'email': REQUESTED_FOR_EMAIL})
if USER_TARGET == '' and USER_REPO == 'https://github.com/Azure/azure-cli.git' and USER_BRANCH == 'dev' and USER_LIVE == '--live' and REQUESTED_FOR_EMAIL == '':
data['personalizations'][0]['to'].append({'email': '[email protected]'})
print(data)

sendgrid_key = sys.argv[1]
sg = SendGridAPIClient(sendgrid_key)
Expand Down
4 changes: 2 additions & 2 deletions scripts/live_test/test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ class TestData:
Model for testing results
"""
def __init__(self, artifact_dir):
# Value of the list should be (module_name, failed, passed, pass_rate)
# Value of the list should be (module_name, passed, failed, pass_rate)
self.modules = []
# ('Total', failed, passed, pass_rate)
# ('Total', passed, failed, pass_rate)
self.total = None
self.artifact_dir = artifact_dir

Expand Down