Skip to content

Commit

Permalink
read last reboot-cause from symlink file
Browse files Browse the repository at this point in the history
  • Loading branch information
sujinmkang committed Oct 13, 2020
1 parent c4b2b6c commit d8977fe
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 20 deletions.
46 changes: 26 additions & 20 deletions show/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1806,14 +1806,30 @@ def mmu():
@click.argument('history', required=False, type=click.Choice(["history"]))
def reboot_cause(history):
"""Show cause of reboot"""
if history:
REBOOT_CAUSE_TABLE = "REBOOT_CAUSE"
TABLE_NAME_SEPARATOR = '|'
REBOOT_CAUSE_DIR = "/host/reboot-cause/"
PREVIOUS_REBOOT_CAUSE_DIR = "/host/reboot-cause/previous-reboot-cause/"
PREVIOUS_REBOOT_CAUSE_FILE = REBOOT_CAUSE_DIR + "previous-reboot-cause.txt"
USER_ISSUE_REBOOT_CAUSE_REGEX ="User issued \'{}\' command [User: {}, Time: {}]"
REBOOT_CAUSE_UNKNOWN = "Unknown"

def read_last_reboot_cause():
last_reboot_cause = REBOOT_CAUSE_UNKNOWN
# Read the last previous reboot cause
if os.path.exists(PREVIOUS_REBOOT_CAUSE_FILE):
with open(PREVIOUS_REBOOT_CAUSE_FILE, "r") as last_cause_file:
data = json.load(last_cause_file)
if data['user']:
last_reboot_cause = USER_ISSUE_REBOOT_CAUSE_REGEX.format(data['cause'], data['user'], data['time'])
else:
last_reboot_cause = "{}".format(data['cause'])
return last_reboot_cause

def read_reboot_cause_dbs():
REBOOT_CAUSE_TABLE_NAME = "REBOOT_CAUSE"
TABLE_NAME_SEPARATOR = '|'
db = SonicV2Connector(host='127.0.0.1')
db.connect(db.STATE_DB, False) # Make one attempt only

prefix = REBOOT_CAUSE_TABLE + TABLE_NAME_SEPARATOR
prefix = REBOOT_CAUSE_TABLE_NAME + TABLE_NAME_SEPARATOR
_hash = '{}{}'.format(prefix, '*')
table_keys = db.keys(db.STATE_DB, _hash)
table_keys.sort(reverse=True)
Expand Down Expand Up @@ -1847,26 +1863,16 @@ def remove_prefix(text, prefix):
r.append("")
else:
r.append(entry['comment'])

table.append(r)
return table

if not history:
click.echo(read_last_reboot_cause())
else:
table = read_reboot_cause_dbs()
header = ['name', 'cause', 'time', 'user', 'comment']
click.echo(tabulate(table, header))

else:
PREVIOUS_REBOOT_CAUSE_FILE = "/host/reboot-cause/previous-reboot-cause.txt"

# At boot time, PREVIOUS_REBOOT_CAUSE_FILE is generated based on
# the contents of the 'reboot cause' file as it was left when the device
# went down for reboot. This file should always be created at boot,
# but check first just in case it's not present.
if not os.path.isfile(PREVIOUS_REBOOT_CAUSE_FILE):
click.echo("Unable to determine cause of previous reboot\n")
else:
cmd = "cat {}".format(PREVIOUS_REBOOT_CAUSE_FILE)
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
click.echo(proc.stdout.read())


#
# 'line' command ("show line")
Expand Down
84 changes: 84 additions & 0 deletions tests/show_reboot_cause.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import os
import sys
import textwrap

import mock
from click.testing import CliRunner

test_path = os.path.dirname(os.path.abspath(__file__))
modules_path = os.path.dirname(test_path)
sys.path.insert(0, modules_path)

import show.main as show


TEST_REBOOT_CAUSE = "warm-reboot"
TEST_USER = "admin"
TEST_REBOOT_TIME = "Fri Oct 9 04:51:47 UTC 2020"


"""
Note: The following 'show reboot-cause' commands simply call other SONiC
CLI utilities, so the unit tests for the other utilities are expected
to cover testing their functionality:
show reboot-cause
show reboot-cause history
"""

class TestShowRebootCause(object):
@classmethod
def setup_class(cls):
print("SETUP")
os.environ["UTILITIES_UNIT_TESTING"] = "1"

def generate_hist_table(self):
table = []
for i in 2:
r = []
if i == 1:
r.append("2020_10_09_04_53_58")
r.append("warm-reboot")
r.append("Fri Oct 9 04:51:47 UTC 2020")
r.append("admin")
r.append("")
else:
r.append("2020_10_09_02_33_06")
r.append("reboot")
r.append("2020_10_09_02_33_06")
r.append("admin")
r.append("")
table.append(r)
return table

# Test 'show reboot-cause'
def test_reboot_cause(self):
expected_output = """\
User issued \'{}\' command [User: {}, Time: {}]
""".format(TEST_REBOOT_CAUSE, TEST_USER, TEST_REBOOT_TIME)

with mock.patch("show.main.read_last_reboot_cause",
return_value={"User issued \'warm-reboot\' command [User: admin, Time: Fri Oct 9 04:51:47 UTC 2020]"}):
runner = CliRunner()
result = runner.invoke(show.cli.commands["reboot-cause"], [])
assert result.output == textwrap.dedent(expected_output)

# Test 'show reboot-cause history'
def test_reboot_cause_history(self):
expected_output = """\
name cause time user comment
------------------- ----------- ---------------------------- ------ ---------
2020_10_09_04_53_58 warm-reboot Fri Oct 9 04:51:47 UTC 2020 admin
2020_10_09_02_33_06 reboot Fri Oct 9 02:29:44 UTC 2020 admin
"""
with mock.patch("show.main.read_reboot_cause_dbs",
return_value={generate_hist_table()}
runner = CliRunner()
result = runner.invoke(show.cli.commands["reboot-cause"].commands[history], [])
assert result.output == expected_output

@classmethod
def teardown_class(cls):
print("TEARDOWN")
os.environ["PATH"] = os.pathsep.join(os.environ["PATH"].split(os.pathsep)[:-1])
os.environ["UTILITIES_UNIT_TESTING"] = "0"

0 comments on commit d8977fe

Please sign in to comment.