☃ Python lib to fetch CI statistics from Travis, CircleCI, Jenkins, or Bamboo
Python lib to fetch CI statistics from common RESTful services as circleci, travis, jekins, or bamboo.
This Python lib is derived from personal project circleci_stat on Github.
After moving to this lib, the original circleci_stat will be in just maintenance status and the results could be a test source to cistat.
The original idea is inspired by a fast ont-time script to count high runners of internal CI test from Bamboo achieved files.
At that time, our project was a Python app and the artifacts were in XUnit common format to enable Jenkins plugins.
With the fast prototype we can also compare the failure rate between Jenkins test statistics and Bamboo data.
This was due to the unstable external dependencies of this project. The prototype was fast and working well.
Based on the statistic hints, we can put more efforts on the high runners to mitigate the interrupt to developerment and test team and reduce the DevOps diagnose time.
By the way, a similar tool Bamboo_XUnit_Reader could be found on Github.
So far only XUnit format artifacts are implemented. In the future, more measurement as “CodeQuality” cloud service, Lint score, Coverage history charts will be considered.
By the way, for a comparison between CircleCI, Travis-CI and Jenkins, readers could refer to this article
Install cistat Pypi dist with dev branch latest code from Github:
pip install https://github.com/maxwu/cistat/archive/dev.zip
# or
pip install git+https://github.com/maxwu/cistat.git@dev
Install cistat from master (release) branch on Github:
pip install https://github.com/maxwu/cistat/archive/master.zip
# or
pip install git+https://github.com/maxwu/cistat.git
For configuration items, cistat will take parameters in a predefined precedence that the closer to running context, the higher priority which configuration record can have.
If there are items provided by calling context, e.g. in arguments list, they are taken directly and precedes.
Otherwise, cistat will check if it exists in environment variables. Which it inherited from process creation and environment could be customized per process for various user scenarios.
At last, cistat will seek parameters from configuration file ~/.cistat/config.yaml.
When all above approaches miss, cistat will utilize the default settings for all occasions.
Configuration records are generally maintained in $HOME/.cistat/config.yaml
v0.91 preview has on key to fill:circleci_api_token: $YOUR_CIRCLECI_API_TOKEN
Disk cache for CI data fetch is by default enabled and located to $HOME/.cistat/cache
. The flag as well as disk size limit, renew policy, update period will be merged to the configuration file soon.
So far the cache is configured as:
cache_expire = 3600*24*14 # 2wk
cache_size = 2**25 # 32MB
Cli entry point to initialize and alter configuration items is not present by v0.91. Users have to create it manually or wrap parameters to environmental variables.
There is no global configuration file besides the above one under $HOME. One possible but not recommended way is to add a config.yaml to parent folder of package path of “cistat”. This file will supercede those under $HOME/.cistat.
Reminder: If your project is on remote repository as Github or BitBucket, please be kindly reminded to add this file to .gitignore
and do not expose it accidentally.
vcs, project, username = 'github', 'cistat', 'maxwu'
urls = CircleCiReq.get_recent_artifacts(vcs=vcs, project=project, username=username)
# XUnit Report Object supports operator '+' and '+='
report = Xunitrpt()
for artifact in urls:
print("fetching {}".format(artifact))
report += Xunitrpt(xunit=CircleCiReq.get_artifact_report(url=artifact))
Extract top 10 failure test cases and the statistics:
import pprint
print("Top 10 failure cases:")
pprint.pprint(report.get_cases_in_rate()[:10])
Pie Chart
report.get_class_rpt().plot_piechart_casenum(project, "Case Num per Class")
The Pie Chart for case numbers per class level is:
Link to original sized Pie Chart
Bar Chart
report.plot_barchart_rate(project, "Pass Rate per case")
The Bar Chart of Pass Rate for cistat project is:
Link to original sized Bar Chart
Bubble Chart
The ROI chart is more considerable for nightly build result analysis in a testing project within XUnit test framework to control the resources as case, docker/cpu, feature integration.
In the sample height of bubble represents the pass rate and the size of bubble shows the test efforts (Currently it is simply the case number; It will be updated to a formula on test time and case number).
The lower the bubble positions, the bigger it shall grow to get more resource and invest to float up to 1.0 the stable status.
report.get_class_rpt().plot_scatter_roi(project, "Test ROI per Class")
The Bubble Chart to present case ROI per class as below:
Link to original sized Bubble Chart
Quick step to run above sample: cistat-cli
. Since circleci.com has throttling limit on RESTful API, it is recommended to configure an API-Key in environmental variable or local config.yaml.
This console command is installed with Pypi dist. cistat-cli
is the console entry point planted by PIP installer setup.py.
>cistat-cli -h
Usage:
cistat --sample
cistat (-h | --help)
cistat (-v | --version)
Options:
-h --help Show this help message
-v --version Print cistat version
--sample Show sample statistic charts
Fetching statistic from cloud or on premise CI function is ready within Python package. CLI shall add this as well in next release.
Fetching cloud or on premise CI result on latest commit will be added next release.
Run nosetests_ci-stat.sh
, or nosetests execution under ./test folder.
Cloud based UT on Travis and Circle.
Configuration item preference order is:
Cli Options >> Environment Variables >> Local Config.yaml
Configuration items:
To test string length with shell,
printf $STR | wc -c
The target is to deliver a lib which could fetch CI test results from widely used CI services as TravisCI, CircelCI, on-premise Jenkins and finally can define customized scheme for any XUnit artifacts.
This lib offers statistics functions on these artifacts.
CircleCI functions developed and tested.
(Low priority since cache speeds up queries)
HATEOAS guarantee backend the freedom of evolution but starts from endpoint(s)
and deduce the following hyperlinks to trigger state transitions on resources
[ ] Add func.name to key to distinguish cache records.
Reserved after v1.0
Cloud CI Services:
On-Premise CI Services:
Local CI files:
Requests:
XUnit Artifacts:
Report:
JUnit with Cucumber-JVM generated XUnit file but the format is weird on parameterized cases.
Action: pending, will get back to Cucumber-JVM after releasing v1.0;
<testcase classname="| 65535 | 117995 |" name="| 65535 | 117995 |" time="0.038">
<failure message="expected:<[117995]> but was:<[32]>" type="org.junit.ComparisonFailure">org.junit.ComparisonFailure: expected:<[117995]> but was:<[32]>
at org.junit.Assert.assertEquals(Assert.java:115)
at org.junit.Assert.assertEquals(Assert.java:144)
at org.maxwu.jrefresh.selenium.stepdefs.TemperatureConverterCalStepdef.check_fahrenheit_degree(TemperatureConverterCalStepdef.java:170)
at ✽.Then Check the value against "117995"(10_Convert_Celsius_To_Fahrenheit.feature:21)
</failure>
</testcase>