about summary refs log tree commit diff homepage
path: root/scripts/coverageServer.py
blob: 9be8c26deefa77ceeabd0c06e1ed98e7cb1e5fbe (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/usr/bin/env python

# ===-- coverageServer.py -------------------------------------------------===##
# 
#                      The KLEE Symbolic Virtual Machine
# 
#  This file is distributed under the University of Illinois Open Source
#  License. See LICENSE.TXT for details.
# 
# ===----------------------------------------------------------------------===##

from flask import *
from functools import wraps
from subprocess import call
from werkzeug import secure_filename
import json
import time
import os
import shutil
import tarfile

##################### DESCRIPTION #################
#This is the server to which coverage data is uploaded from travisCI.
#need to replace USER and PASSWORD with an actual username and passsword used to autheticate in /api
#Stored here, because it needs to be in version control somewhere
#
# Example of running the server
#uwsgi -s 127.0.0.1:3013 -w coverageServer:app --chmod=666 --post-buffering=81 --daemonize ./log
#where nginx is expecting uwsgi traffic at 127.0.0.1:3013


#sample upload command
#curl --form "file=@coverage.tar.gz" -u USER:PASSWORD localhost:5000/api




UPLOAD_FOLDER = '.'

#enable upload only every 5 minutes

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024

TIMEOUT = 0


def check_auth(username, password):
    return username == 'USER' and password == 'PASSWORD'


def authenticate():
    """Sends a 401 response that enables basic auth"""
    return Response(
    'Could not verify your access level for that URL.\n'
    'You have to login with proper credentials', 401,
    {'WWW-Authenticate': 'Basic realm="Login Required"'})


def requires_auth(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        auth = request.authorization
        if not auth or not check_auth(auth.username, auth.password):
            return authenticate()
        return f(*args, **kwargs)
    return decorated

@app.route("/<path:path>")
def serve_page(path):
	return send_from_directory('./coverage', path)

#check that the tar file has only one efolder named coverage
def check_tar(tar):
	coverage_dir_num = 0
	for tarinfo in tar.getmembers():
		if 'coverage' in tarinfo.name and tarinfo.isdir(): 
			coverage_dir_num += 1
		elif not 'coverage/' in tarinfo.name:
			return False
	return coverage_dir_num == 1

@app.route("/api", methods=['POST'])
@requires_auth
def upload_coverage():
    global TIMEOUT
#only allow uploads every 5 minutes (a bit less than usuall travisCI build)
    if time.time() - TIMEOUT < 300:
	    return "Time Out"
    if request.method == 'POST':
        file = request.files['file']
	if file.filename == "coverage.tar.gz":  
          filename = secure_filename(file.filename)
          file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
          tar = tarfile.open("./coverage.tar.gz")
	  if not check_tar(tar):
		return "NOK"
#remove the previous coverage folder if it existis
      if os.path.isdir("./coverage"):
    	    shutil.rmtree("./coverage")
      tar.extractall()
      tar.close()
	  TIMEOUT = time.time()
      return "OK"
    return "NOK"

if __name__ == "__main__":
    app.debug = True
    app.run(host="0.0.0.0")