1#! /usr/bin/python 2 3# Copyright 2014 The Chromium OS Authors. All rights reserved. 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7"""Unit tests for commands.py.""" 8 9import copy 10import mox 11import unittest 12 13import common 14from fake_device_server import commands 15from fake_device_server import fake_oauth 16from fake_device_server import fail_control 17from fake_device_server import server_errors 18 19 20class CommandsTest(mox.MoxTestBase): 21 """Tests for the Commands class. 22 23 Note unlike other unittests in this project, I set the api_key for all 24 tests. This makes the logic easier to read because of the additional 25 dictionary mapping of 26 # commands.devices_commands[(id, api_key)] = dict of commands by command id. 27 """ 28 29 def setUp(self): 30 """Sets up mox and a ticket / registration objects.""" 31 mox.MoxTestBase.setUp(self) 32 # Use a fake OAuth module to work around the hack that this 33 # module bypass cherrypy by directly invoking commands.GET. 34 self.oauth = fake_oauth.FakeOAuth() 35 self.fail_control = fail_control.FailControl() 36 self.commands = commands.Commands(self.oauth, self.fail_control) 37 38 39 def testCreateCommand(self): 40 """Tests that we can create a new command.""" 41 DEVICE_ID = '1234awesomeDevice' 42 GOOD_COMMAND = { 43 'deviceId': DEVICE_ID, 44 'name': 'base._vendorCommand', 45 'base': { 46 '_vendorCommand': { 47 'name': 'specialCommand', 48 'kind': 'buffetSpecialCommand', 49 } 50 } 51 } 52 53 self.commands.new_device(DEVICE_ID) 54 new_command = self.commands.create_command(GOOD_COMMAND) 55 self.assertTrue('id' in new_command) 56 command_id = new_command['id'] 57 self.assertEqual(new_command['state'], 'queued') 58 self.assertEqual( 59 self.commands.device_commands[DEVICE_ID][command_id], 60 new_command) 61 62 # Test command without necessary nesting. 63 bad_command = {'base': {}} 64 self.assertRaises(server_errors.HTTPError, 65 self.commands.create_command, bad_command) 66 67 # Test adding a good command to an unknown device. 68 BAD_COMMAND = copy.deepcopy(GOOD_COMMAND) 69 BAD_COMMAND['deviceId'] = 'not_a_real_device' 70 self.assertRaises(server_errors.HTTPError, 71 self.commands.create_command, BAD_COMMAND) 72 73 74 def testGet(self): 75 """Tests that we can retrieve a command correctly.""" 76 DEVICE_ID = 'device_id' 77 COMMAND_ID = 'command_id' 78 COMMAND_RESOURCE = {'faked': 'out'} 79 self.commands.new_device(DEVICE_ID) 80 self.commands.device_commands[DEVICE_ID][COMMAND_ID] = COMMAND_RESOURCE 81 returned_json = self.commands.GET(COMMAND_ID, deviceId=DEVICE_ID) 82 self.assertEquals(returned_json, COMMAND_RESOURCE) 83 84 BAD_COMMAND_ID = 'fubar' 85 # Non-existing command. 86 self.assertRaises(server_errors.HTTPError, 87 self.commands.GET, BAD_COMMAND_ID) 88 89 90 def testListing(self): 91 """Tests that we can get a listing back correctly using the GET method. 92 """ 93 DEVICE_ID = 'device_id' 94 COMMAND = { 95 'name': 'base.reboot', 96 'deviceId': DEVICE_ID, 97 } 98 self.commands.new_device(DEVICE_ID) 99 command1 = self.commands.create_command(copy.deepcopy(COMMAND)) 100 command2 = self.commands.create_command(copy.deepcopy(COMMAND)) 101 command1_id = command1['id'] 102 command2_id = command2['id'] 103 self.commands.device_commands[DEVICE_ID][command1_id]['state'] = \ 104 'inProgress' 105 106 # Without state should return all commands. 107 def check_has_commands(expected_ids, state=None): 108 """Check that we get all the commands we expect given a state. 109 110 @param expected_ids: list of string command ids. 111 @param state: Optional state to filter on (a string like 'queued' 112 113 """ 114 returned_json = self.commands.GET(deviceId=DEVICE_ID, state=state) 115 self.assertEqual('clouddevices#commandsListResponse', 116 returned_json['kind']) 117 self.assertTrue('commands' in returned_json) 118 returned_command_ids = [command['id'] 119 for command in returned_json['commands']] 120 self.assertEqual(sorted(returned_command_ids), sorted(expected_ids)) 121 122 check_has_commands([command1_id, command2_id]) 123 check_has_commands([command1_id], state='inProgress') 124 125 126if __name__ == '__main__': 127 unittest.main() 128