1#!/usr/bin/env python
2#
3# Copyright (c) 2016, The OpenThread Authors.
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions are met:
8# 1. Redistributions of source code must retain the above copyright
9#    notice, this list of conditions and the following disclaimer.
10# 2. Redistributions in binary form must reproduce the above copyright
11#    notice, this list of conditions and the following disclaimer in the
12#    documentation and/or other materials provided with the distribution.
13# 3. Neither the name of the copyright holder nor the
14#    names of its contributors may be used to endorse or promote products
15#    derived from this software without specific prior written permission.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27# POSSIBILITY OF SUCH DAMAGE.
28#
29
30import ConfigParser
31import logging
32import os
33import subprocess
34import time
35
36from autothreadharness import settings
37
38logger = logging.getLogger(__name__)
39
40HARNESS_SVN_VERSION_R44 = 1471
41"""int: this is the first published release that miniweb was removed from Harness"""
42
43
44def _try_kill(proc):
45    logger.info('Try kill process')
46    times = 1
47
48    while proc.poll() is None:
49        proc.kill()
50
51        time.sleep(5)
52
53        if proc.poll() is not None:
54            logger.info('Process has been killed')
55            break
56
57        logger.info('Trial %d failed', times)
58        times += 1
59
60        if times > 3:
61            raise SystemExit()
62
63
64class HarnessController(object):
65    """Harness service control
66
67    This controls harness service, including the harness back-end and front-end.
68    """
69
70    harness = None
71    """harness back-end"""
72
73    miniweb = None
74    """harness front-end"""
75
76    def __init__(self, result_dir=None):
77        self.result_dir = result_dir
78        self.harness_file = ''
79
80        harness_info = ConfigParser.ConfigParser()
81        harness_info.read('%s\\info.ini' % settings.HARNESS_HOME)
82        self.version = harness_info.getint('Thread_Harness_Info', 'SVN')
83
84    def start(self):
85        logger.info('Starting harness service')
86        if self.harness:
87            logger.warning('Harness already started')
88        else:
89            env = dict(
90                os.environ,
91                PYTHONPATH='%s\\Thread_Harness;%s\\ThirdParty\\hsdk-python\\src' %
92                (settings.HARNESS_HOME, settings.HARNESS_HOME),
93            )
94
95            self.harness_file = '%s\\harness-%s.log' % (self.result_dir, time.strftime('%Y%m%d%H%M%S'))
96            with open(self.harness_file, 'w') as harness_out:
97                self.harness = subprocess.Popen(
98                    [
99                        settings.HARNESS_HOME + '\\Python27\\python.exe',
100                        settings.HARNESS_HOME + '\\Thread_Harness\\Run.py',
101                    ],
102                    cwd=settings.HARNESS_HOME,
103                    stdout=harness_out,
104                    stderr=harness_out,
105                    env=env,
106                )
107            time.sleep(2)
108
109        if self.version >= HARNESS_SVN_VERSION_R44:
110            return
111
112        if self.miniweb:
113            logger.warning('Miniweb already started')
114        else:
115            with open('%s\\miniweb-%s.log' % (self.result_dir, time.strftime('%Y%m%d%H%M%S')), 'w') as miniweb_out:
116                self.miniweb = subprocess.Popen(
117                    [settings.HARNESS_HOME + '\\MiniWeb\\miniweb.exe'],
118                    stdout=miniweb_out,
119                    stderr=miniweb_out,
120                    cwd=settings.HARNESS_HOME + '\\MiniWeb',
121                )
122
123    def stop(self):
124        logger.info('Stopping harness service')
125
126        if self.harness:
127            _try_kill(self.harness)
128            self.harness = None
129        else:
130            logger.warning('Harness not started yet')
131
132        if self.version >= HARNESS_SVN_VERSION_R44:
133            return
134
135        if self.miniweb:
136            _try_kill(self.miniweb)
137            self.miniweb = None
138        else:
139            logger.warning('Miniweb not started yet')
140
141    def tail(self):
142        with open(self.harness_file) as harness_out:
143            harness_out.seek(-100, 2)
144            return ''.join(harness_out.readlines())
145
146    def __del__(self):
147        self.stop()
148