Skip to content

Commit ce4d105

Browse files
committed
Stopping and resuming long running compile tests to avoid saucelabs timeout.
(useful for compiles of examples). Tests stop after 2.5 hours of testing. To resume, the last available log is loaded and tests continue the compiles when more urls are left to follow compared to the loaded log.
1 parent 2458222 commit ce4d105

File tree

1 file changed

+65
-8
lines changed

1 file changed

+65
-8
lines changed

codebender_testing/utils.py

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
from contextlib import contextmanager
22
from time import gmtime
33
from time import strftime
4+
from time import strptime
45
from urlparse import urlparse
6+
import time
57
import random
68
import os
79
import re
810
import shutil
9-
import time
1011
import tempfile
1112
import simplejson
1213
import pytest
@@ -73,6 +74,10 @@ def _move_file_to_dropzone_script(dropzone_selector):
7374
VERIFICATION_SUCCESSFUL_MESSAGE = "Verification Successful"
7475
VERIFICATION_FAILED_MESSAGE = "Verification failed."
7576

77+
# Max test runtime into saucelabs
78+
# 2.5 hours (3 hours max)
79+
SAUCELABS_TIMEOUT_SECONDS = 10800 - 1800
80+
7681
# Throttle between compiles
7782
COMPILES_PER_MINUTE = 10
7883
def throttle_compile():
@@ -85,6 +90,31 @@ def throttle_compile():
8590
with open(BOARDS_PATH) as f:
8691
BOARDS_DB = simplejson.loads(f.read())
8792

93+
def read_last_log(compile_type):
94+
logs = os.listdir(get_path('logs'))
95+
logs_re = re.compile(r'.+cb_compile_tester.+')
96+
if compile_type == 'library':
97+
logs_re = re.compile(r'.+libraries_test.+')
98+
logs = sorted([x for x in logs if x != '.gitignore' and logs_re.match(x)])
99+
100+
log_timestamp_re = re.compile(r'(\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2})-.+\.json')
101+
log = None
102+
timestamp = None
103+
if len(logs) > 0:
104+
log = logs[-1]
105+
timestamp = log_timestamp_re.match(log).group(1)
106+
107+
last_log = None
108+
if log:
109+
with open(get_path('logs', log)) as f:
110+
last_log = simplejson.loads(f.read())
111+
112+
return {
113+
'log': last_log,
114+
'timestamp': timestamp
115+
}
116+
117+
88118
# Creates a report json after each compile test
89119
def report_creator(compile_type, log_entry, log_file):
90120
logs = os.listdir(get_path('logs'))
@@ -429,19 +459,39 @@ def compile_sketches(self, sketches, iframe=False, logfile=None, compile_type='s
429459

430460
# Log filename
431461
log_time = gmtime()
462+
# Keeps the logs of each compile
463+
log_entry = {}
464+
465+
urls_visited = {}
466+
last_log = read_last_log(compile_type)
467+
if last_log['log']:
468+
# resume previous compile
469+
log_time = strptime(last_log['timestamp'], '%Y-%m-%d_%H-%M-%S')
470+
log_entry = last_log['log']
471+
for url in last_log['log']:
472+
urls_visited[url] = True
473+
474+
urls_to_visit = []
475+
for url in sketches:
476+
if url not in urls_visited:
477+
urls_to_visit.append(url)
478+
479+
if len(urls_to_visit) == 0:
480+
urls_to_visit = sketches
481+
log_entry = {}
482+
log_time = gmtime()
483+
432484
current_date = strftime('%Y-%m-%d', log_time)
433485
# Initialize DisqusWrapper
434486
disqus_wrapper = DisqusWrapper(log_time)
435487
if logfile:
436488
log_file = strftime(logfile, log_time)
437-
# Keeps the logs of each compile
438-
log_entry = {}
439-
# Compile all the input when in Full mode or a single sketch/example
440-
sketches = sketches if self.run_full_compile_tests else sketches[0:1]
441489

442-
print '\nCompiling:', len(sketches), 'sketches'
443-
total_sketches = len(sketches)
444-
for counter, sketch in enumerate(sketches):
490+
print '\nCompiling:', len(urls_to_visit), 'sketches'
491+
total_sketches = len(urls_to_visit)
492+
tic = time.time()
493+
494+
for counter, sketch in enumerate(urls_to_visit):
445495
# Read the boards map in case current sketch/example requires a special board configuration
446496
boards = BOARDS_DB['default_boards']
447497
url_fragments = urlparse(sketch)
@@ -497,9 +547,16 @@ def compile_sketches(self, sketches, iframe=False, logfile=None, compile_type='s
497547

498548
print '.',
499549

550+
toc = time.time()
551+
if toc - tic >= SAUCELABS_TIMEOUT_SECONDS:
552+
print '\nStopping tests to avoid saucelabs timeout'
553+
print 'Test duration:', int(toc - tic), 'sec'
554+
return
555+
500556
# Generate a report if requested
501557
if create_report:
502558
report_creator(compile_type, log_entry, log_file)
559+
print '\nTest duration:', int(toc - tic), 'sec'
503560

504561
def execute_script(self, script, *deps):
505562
"""Waits for all JavaScript variables in `deps` to be defined, then

0 commit comments

Comments
 (0)