1#!/usr/bin/env python
2# Copyright 2013 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Tests for the cmd_helper module."""
7
8import unittest
9import subprocess
10
11from devil.utils import cmd_helper
12
13
14class CmdHelperSingleQuoteTest(unittest.TestCase):
15
16  def testSingleQuote_basic(self):
17    self.assertEquals('hello',
18                      cmd_helper.SingleQuote('hello'))
19
20  def testSingleQuote_withSpaces(self):
21    self.assertEquals("'hello world'",
22                      cmd_helper.SingleQuote('hello world'))
23
24  def testSingleQuote_withUnsafeChars(self):
25    self.assertEquals("""'hello'"'"'; rm -rf /'""",
26                      cmd_helper.SingleQuote("hello'; rm -rf /"))
27
28  def testSingleQuote_dontExpand(self):
29    test_string = 'hello $TEST_VAR'
30    cmd = 'TEST_VAR=world; echo %s' % cmd_helper.SingleQuote(test_string)
31    self.assertEquals(test_string,
32                      cmd_helper.GetCmdOutput(cmd, shell=True).rstrip())
33
34
35class CmdHelperDoubleQuoteTest(unittest.TestCase):
36
37  def testDoubleQuote_basic(self):
38    self.assertEquals('hello',
39                      cmd_helper.DoubleQuote('hello'))
40
41  def testDoubleQuote_withSpaces(self):
42    self.assertEquals('"hello world"',
43                      cmd_helper.DoubleQuote('hello world'))
44
45  def testDoubleQuote_withUnsafeChars(self):
46    self.assertEquals('''"hello\\"; rm -rf /"''',
47                      cmd_helper.DoubleQuote('hello"; rm -rf /'))
48
49  def testSingleQuote_doExpand(self):
50    test_string = 'hello $TEST_VAR'
51    cmd = 'TEST_VAR=world; echo %s' % cmd_helper.DoubleQuote(test_string)
52    self.assertEquals('hello world',
53                      cmd_helper.GetCmdOutput(cmd, shell=True).rstrip())
54
55
56class CmdHelperShinkToSnippetTest(unittest.TestCase):
57
58  def testShrinkToSnippet_noArgs(self):
59    self.assertEquals('foo',
60        cmd_helper.ShrinkToSnippet(['foo'], 'a', 'bar'))
61    self.assertEquals("'foo foo'",
62        cmd_helper.ShrinkToSnippet(['foo foo'], 'a', 'bar'))
63    self.assertEquals('"$a"\' bar\'',
64        cmd_helper.ShrinkToSnippet(['foo bar'], 'a', 'foo'))
65    self.assertEquals('\'foo \'"$a"',
66        cmd_helper.ShrinkToSnippet(['foo bar'], 'a', 'bar'))
67    self.assertEquals('foo"$a"',
68        cmd_helper.ShrinkToSnippet(['foobar'], 'a', 'bar'))
69
70  def testShrinkToSnippet_singleArg(self):
71    self.assertEquals("foo ''",
72        cmd_helper.ShrinkToSnippet(['foo', ''], 'a', 'bar'))
73    self.assertEquals("foo foo",
74        cmd_helper.ShrinkToSnippet(['foo', 'foo'], 'a', 'bar'))
75    self.assertEquals('"$a" "$a"',
76        cmd_helper.ShrinkToSnippet(['foo', 'foo'], 'a', 'foo'))
77    self.assertEquals('foo "$a""$a"',
78        cmd_helper.ShrinkToSnippet(['foo', 'barbar'], 'a', 'bar'))
79    self.assertEquals('foo "$a"\' \'"$a"',
80        cmd_helper.ShrinkToSnippet(['foo', 'bar bar'], 'a', 'bar'))
81    self.assertEquals('foo "$a""$a"\' \'',
82        cmd_helper.ShrinkToSnippet(['foo', 'barbar '], 'a', 'bar'))
83    self.assertEquals('foo \' \'"$a""$a"\' \'',
84        cmd_helper.ShrinkToSnippet(['foo', ' barbar '], 'a', 'bar'))
85
86
87class CmdHelperIterCmdOutputLinesTest(unittest.TestCase):
88  """Test IterCmdOutputLines with some calls to the unix 'seq' command."""
89
90  def testIterCmdOutputLines_success(self):
91    for num, line in enumerate(
92        cmd_helper.IterCmdOutputLines(['seq', '10']), 1):
93      self.assertEquals(num, int(line))
94
95  def testIterCmdOutputLines_exitStatusFail(self):
96    with self.assertRaises(subprocess.CalledProcessError):
97      for num, line in enumerate(
98          cmd_helper.IterCmdOutputLines('seq 10 && false', shell=True), 1):
99        self.assertEquals(num, int(line))
100      # after reading all the output we get an exit status of 1
101
102  def testIterCmdOutputLines_exitStatusIgnored(self):
103    for num, line in enumerate(
104        cmd_helper.IterCmdOutputLines('seq 10 && false', shell=True,
105                                      check_status=False), 1):
106      self.assertEquals(num, int(line))
107
108  def testIterCmdOutputLines_exitStatusSkipped(self):
109    for num, line in enumerate(
110        cmd_helper.IterCmdOutputLines('seq 10 && false', shell=True), 1):
111      self.assertEquals(num, int(line))
112      # no exception will be raised because we don't attempt to read past
113      # the end of the output and, thus, the status never gets checked
114      if num == 10:
115        break
116
117
118if __name__ == '__main__':
119  unittest.main()
120