Re-land: C++ readability review
[chromium-blink-merge.git] / remoting / tools / native_messaging_host_test.py
blob41d0b2e068c4765fdca1f67f4a815e0ef2542c8c
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.
6 # Interactive test script for the Chromoting host native messaging component.
8 import json
9 import readline
10 import struct
11 import subprocess
12 import sys
15 def PrintMenuAndGetBuilder(messages):
16 print
17 for i in range(0, len(messages)):
18 print '%d: %s' % (i + 1, messages[i][0])
19 print 'Q: Quit'
20 while True:
21 choice = raw_input('Enter choice: ')
22 if choice.lower() == 'q':
23 return None
24 choice = int(choice)
25 if choice >= 1 and choice <= len(messages):
26 return messages[choice - 1][1]
29 # Message builder methods.
30 def BuildHello():
31 return {'type': 'hello'}
34 def BuildClearAllPairedClients():
35 return {'type': 'clearPairedClients'}
38 def BuildDeletePairedClient():
39 client_id = raw_input('Enter client id: ')
40 return {'type': 'deletePairedClient',
41 'clientId': client_id}
44 def BuildGetHostName():
45 return {'type': 'getHostName'}
48 def BuildGetPinHash():
49 host_id = raw_input('Enter host id: ')
50 pin = raw_input('Enter PIN: ')
51 return {'type': 'getPinHash',
52 'hostId': host_id,
53 'pin': pin}
56 def BuildGenerateKeyPair():
57 return {'type': 'generateKeyPair'}
60 def BuildUpdateDaemonConfig():
61 config_json = raw_input('Enter config JSON: ')
62 return {'type': 'updateDaemonConfig',
63 'config': config_json}
66 def BuildGetDaemonConfig():
67 return {'type': 'getDaemonConfig'}
70 def BuildGetPairedClients():
71 return {'type': 'getPairedClients'}
74 def BuildGetUsageStatsConsent():
75 return {'type': 'getUsageStatsConsent'}
78 def BuildStartDaemon():
79 while True:
80 consent = raw_input('Report usage stats [y/n]? ')
81 if consent.lower() == 'y':
82 consent = True
83 elif consent.lower() == 'n':
84 consent = False
85 else:
86 continue
87 break
88 config_json = raw_input('Enter config JSON: ')
89 return {'type': 'startDaemon',
90 'consent': consent,
91 'config': config_json}
94 def BuildStopDaemon():
95 return {'type': 'stopDaemon'}
98 def BuildGetDaemonState():
99 return {'type': 'getDaemonState'}
102 def main():
103 if len(sys.argv) != 2:
104 print 'Usage: ' + sys.argv[0] + ' <path to native messaging host>'
105 sys.exit(1)
107 native_messaging_host = sys.argv[1]
109 child = subprocess.Popen(native_messaging_host, stdin=subprocess.PIPE,
110 stdout=subprocess.PIPE, close_fds=True)
112 message_id = 0
113 while True:
114 messages = [
115 ('Hello', BuildHello),
116 ('Clear all paired clients', BuildClearAllPairedClients),
117 ('Delete paired client', BuildDeletePairedClient),
118 ('Get host name', BuildGetHostName),
119 ('Get PIN hash', BuildGetPinHash),
120 ('Generate key pair', BuildGenerateKeyPair),
121 ('Update daemon config', BuildUpdateDaemonConfig),
122 ('Get daemon config', BuildGetDaemonConfig),
123 ('Get paired clients', BuildGetPairedClients),
124 ('Get usage stats consent', BuildGetUsageStatsConsent),
125 ('Start daemon', BuildStartDaemon),
126 ('Stop daemon', BuildStopDaemon),
127 ('Get daemon state', BuildGetDaemonState)
129 builder = PrintMenuAndGetBuilder(messages)
130 if not builder:
131 break
132 message_dict = builder()
133 message_dict['id'] = message_id
134 message = json.dumps(message_dict)
135 message_id += 1
136 print 'Message: ' + message
137 child.stdin.write(struct.pack('I', len(message)))
138 child.stdin.write(message)
139 child.stdin.flush()
141 reply_length_bytes = child.stdout.read(4)
142 if len(reply_length_bytes) < 4:
143 print 'Invalid message length'
144 break
145 reply_length = struct.unpack('i', reply_length_bytes)[0]
146 reply = child.stdout.read(reply_length).decode('utf-8')
147 print 'Reply: ' + reply
148 if len(reply) != reply_length:
149 print 'Invalid reply length'
150 break
152 if __name__ == '__main__':
153 main()