1# -*- coding: utf-8 -*-
2
3##########################################################################
4# Copyright (c) 2014, ETH Zurich.
5# All rights reserved.
6#
7# This file is distributed under the terms in the attached LICENSE file.
8# If you do not find this file, copies can be found by writing to:
9# ETH Zurich D-INFK, Universit��tstrasse 6, CH-8092 Zurich. Attn: Systems Group.
10##########################################################################
11
12import tests, debug, pexpect
13from common import InteractiveTest
14from results import PassFailResult
15
16START_CPU_DRIVER = "Barrelfish CPU driver starting"
17
18class CoreCtrlTest(InteractiveTest):
19    '''Framework for coreboot test'''
20
21    def get_modules(self, build, machine):
22        modules = super(CoreCtrlTest, self).get_modules(build, machine)
23        if machine.get_ncores() > 2:
24            self.core = 2
25        else:
26            self.core = 1
27        return modules
28
29@tests.add_test
30class StopCoreTest(CoreCtrlTest):
31    '''Stop a core.'''
32
33    name = 'stop_core'
34
35    def get_modules(self, build, machine):
36        modules = super(StopCoreTest, self).get_modules(build, machine)
37        modules.add_module("periodicprint", args=["core=%d" % self.core ])
38        return modules
39
40    def interact(self):
41        self.wait_for_fish()
42
43        # wait for app
44        self.console.expect("On core %s" % self.core)
45
46        debug.verbose("Stopping core %s." % self.core)
47        self.console.sendline("corectrl stop %s\n" % self.core)
48
49        # Stop core
50        debug.verbose("Wait until core is down.")
51        self.console.expect("Core %s stopped." % self.core)
52        # cannot wait for prompt here, as new cleanup routine will wait for
53        # answer from monitor on stopped core.
54        #self.wait_for_prompt()
55
56        debug.verbose("making sure that core is down.")
57        # Make sure app is no longer running
58        i = self.console.expect(["On core %s" % self.core, pexpect.TIMEOUT], timeout=10)
59        debug.verbose("got %d from last expect" % i)
60        if i == 0:
61            raise Exception("periodicprint still running, did we not shut-down the core?")
62
63    def process_data(self, testdir, rawiter):
64        for line in rawiter:
65            if ("Core %s stopped." % self.core) in line:
66                return PassFailResult(True)
67
68        return PassFailResult(False)
69
70
71@tests.add_test
72class UpdateKernelTest(CoreCtrlTest):
73    '''Update a kernel on a core.'''
74
75    name = 'update_kernel'
76
77    def get_modules(self, build, machine):
78        modules = super(UpdateKernelTest, self).get_modules(build, machine)
79        modules.add_module("periodicprint", args=["core=%d" % self.core])
80        return modules
81
82    def interact(self):
83        self.wait_for_fish()
84
85        # wait for app
86        self.console.expect("On core %s" % self.core)
87
88        # Reboot core
89        self.console.sendline("corectrl update %s\n" % self.core)
90        self.console.expect(START_CPU_DRIVER)
91        self.wait_for_prompt()
92
93        # Make sure app is still running
94        self.console.expect("On core %s" % self.core)
95
96    def process_data(self, testdir, rawiter):
97        output_count = 0
98        for line in rawiter:
99            if ("On core %s" % self.core) in line:
100                output_count = output_count + 1
101
102        return PassFailResult(output_count > 1)
103
104
105@tests.add_test
106class ParkOSNodeTest(CoreCtrlTest):
107    '''Park an OSNode on a core.'''
108    name = 'park_osnode'
109
110    def get_modules(self, build, machine):
111        modules = super(ParkOSNodeTest, self).get_modules(build, machine)
112        if machine.get_ncores() > 3:
113            self.target_core = 3
114        else:
115            self.target_core = 0
116        modules.add_module("periodicprint", args=["core=%d" % self.core])
117        return modules
118
119    def interact(self):
120        self.wait_for_fish()
121
122        self.console.expect("On core %s" % self.core)
123
124        # Park
125        debug.verbose("Park OSNode from %s on %s." % (self.core, self.target_core))
126        self.console.sendline("corectrl park %s %s\n" % (self.core, self.target_core))
127        self.wait_for_prompt()
128
129        self.console.expect("On core %s" % self.target_core)
130
131    def process_data(self, testdir, rawiter):
132        for line in rawiter:
133            if ("On core %s" % self.target_core) in line:
134                return PassFailResult(True)
135        return PassFailResult(False)
136
137
138@tests.add_test
139class ListKCBTest(CoreCtrlTest):
140    '''List all KCBs.'''
141    name = 'list_kcb_cores'
142
143    def interact(self):
144        self.wait_for_fish()
145        debug.verbose("Running corectrl lskcb")
146        self.console.sendline("corectrl lskcb")
147        self.console.expect("KCB 0:")
148        self.wait_for_prompt()
149
150        debug.verbose("Running corectrl lscpu")
151        self.console.sendline("corectrl lscpu\n")
152        self.console.expect("CPU 0:")
153        self.wait_for_prompt()
154
155    def process_data(self, testdir, rawiter):
156        found_kcb_output = False
157        found_cpu_output = False
158        for line in rawiter:
159            if "KCB 0:" in line:
160                found_kcb_output = True
161            if "CPU 0:" in line:
162                found_cpu_output = True
163        return PassFailResult(found_kcb_output and found_cpu_output)
164
165
166@tests.add_test
167class ParkRebootTest(CoreCtrlTest):
168    '''Park OSNode and move it back.'''
169    name = 'park_boot'
170
171    def get_modules(self, build, machine):
172        modules = super(ParkRebootTest, self).get_modules(build, machine)
173        self.core = 1
174        if machine.get_ncores() <= 2:
175            self.parking_core = 0
176        else:
177            self.parking_core = 2
178        modules.add_module("periodicprint", args=["core=%d" % self.core])
179        return modules
180
181    def interact(self):
182        self.wait_for_fish()
183
184        self.console.expect("On core %s" % self.core)
185        self.console.expect("On core %s" % self.core)
186
187        # Park
188        debug.verbose("Park KCB %s on core %s." % (self.core, self.parking_core))
189        self.console.sendline("corectrl park %s %s\n" % (self.core, self.parking_core))
190        self.wait_for_prompt()
191
192        self.console.expect("On core %s" % self.parking_core)
193        self.console.expect("On core %s" % self.parking_core)
194
195        # Unpark
196        debug.verbose("Unpark KCB %s from core %s." % (self.core, self.parking_core))
197        self.console.sendline("corectrl unpark %s\n" % (self.core))
198        self.wait_for_prompt()
199
200        # Reboot home core with kcb
201        self.console.expect("On core %s" % self.core)
202        self.console.expect("On core %s" % self.core)
203
204    def process_data(self, testdir, rawiter):
205        output_count = 0
206        parked_count = 0
207
208        for line in rawiter:
209            if ("On core %s" % self.parking_core) in line:
210                parked_count = parked_count + 1
211            if ("On core %s" % self.core) in line:
212                output_count = output_count + 1
213
214        return PassFailResult(parked_count >= 2 and output_count >= 4)
215