aboutsummaryrefslogtreecommitdiff
path: root/lava_dispatcher/connection.py
blob: e17de481de903615149c0e3e05ae703efe15934a (plain)
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# Copyright (C) 2011 Linaro Limited
#
# Author: Michael Hudson-Doyle <michael.hudson@linaro.org>
#
# This file is part of LAVA Dispatcher.
#
# LAVA Dispatcher is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LAVA Dispatcher is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along
# with this program; if not, see <http://www.gnu.org/licenses>.

import logging
import pexpect
import re


class LavaConnection(object):

    def __init__(self, device_config, sio):
        self.device_config = device_config
        self.proc = self._make_connection(sio)

    def _make_connection(self, sio):
        raise NotImplementedError(self._make_connection)

    def device_option(self, option_name):
        return self.device_config.get(option_name)

    def device_option_int(self, option_name):
        return self.device_config.getint(option_name)


    # pexpect-like interface.

    def sendline(self, *args, **kw):
        logging.debug("sendline : %s" %args[0])
        return self.proc.sendline(*args, **kw)

    def send(self, *args, **kw):
        logging.debug("sendline : %s" %args[0])
        return self.proc.send(*args, **kw)

    def expect(self, *args, **kw):
        # some expect should not be logged because it is so much noise.
        if kw.has_key('lava_no_logging'):
            del kw['lava_no_logging']
            return self.proc.expect(*args, **kw)

        if (kw.has_key('timeout')):
            timeout = kw['timeout']
        else:
            timeout = self.proc.timeout

        if len(args) == 1:
            logging.debug("expect (%d): '%s'" %(timeout, args[0]))
        else:
            logging.debug("expect (%d): '%s'" %(timeout, str(args)))
    
        return self.proc.expect(*args, **kw)

    def sendcontrol(self, *args, **kw):
        return self.proc.sendcontrol(*args, **kw)

    @property
    def match(self):
        return self.proc.match


    # Extra bits.

    def _enter_uboot(self):
        self.expect("Hit any key to stop autoboot")
        self.sendline("")

    def soft_reboot(self):
        self.sendline("reboot")
        # set soft reboot timeout 120s, or do a hard reset
        logging.info("Rebooting the system")
        id = self.expect(
            ['Restarting system.', 'The system is going down for reboot NOW',
                'Will now restart', pexpect.TIMEOUT], timeout=120)
        if id not in [0,1,2]:
            self.hard_reboot()

    def hard_reboot(self):
        raise NotImplementedError(self.hard_reboot)


class LavaConmuxConnection(LavaConnection):

    def _make_connection(self, sio):
        cmd = self.device_option("connection_command")
        proc = pexpect.spawn(cmd, timeout=1200, logfile=sio)
        #serial can be slow, races do funny things if you don't increase delay
        proc.delaybeforesend=1
        return proc

    def hard_reboot(self):
        logging.info("Perform hard reset on the system")
        self.proc.send("~$")
        self.proc.sendline("hardreset")

    def _boot(self, boot_cmds):
        self.soft_reboot()
        try:
            self._enter_uboot()
        except:
            logging.exception("_enter_uboot failed")
            self.hard_reboot()
            self._enter_uboot()
        self.sendline(boot_cmds[0])
        bootloader_prompt = re.escape(self.device_option('bootloader_prompt'))
        for line in range(1, len(boot_cmds)):
            self.expect(bootloader_prompt, timeout=300)
            self.sendline(boot_cmds[line])