blob: 7afe4bf01305f56c57686d76aad4f0d27d7ecd0b [file] [log] [blame]
Neels Hofmeyr726b58d2017-10-15 03:01:09 +02001#!/usr/bin/env python3
2#
3# (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
4# All rights reserved.
5#
6# Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20
21'''
22Run CTRL test transcripts against a given application.
23
24A CTRL transcript contains CTRL commands and their expected results.
25It looks like:
26
27"
28SET 1 var val
29SET_REPLY 1 var OK
30GET 2 var
31GET_REPLY 2 var val
32"
33
34The application to be tested is described by
35- a binary to run,
36- command line arguments to pass to the binary,
37- the CTRL port.
38
39This module can either be run directly to run or update a given CTRL transcript,
40or it can be imported as a module to run more complex setups.
41'''
42
43import re
44
45from osmopy.osmo_verify_transcript_common import *
46from osmopy.osmo_ipa import Ctrl, IPA
47
48class InteractCtrl(Interact):
49 next_id = 1
50 keep_ids = True
51 re_command = re.compile('^(SET|GET) ([^ ]*) (.*)$')
52
53 class CtrlStep(Interact.StepBase):
54
55 @staticmethod
56 def is_next_step(line, interact_instance):
57 m = InteractCtrl.re_command.match(line)
58 if not m:
59 return None
60 next_step = InteractCtrl.CtrlStep()
61
62 set_get = m.group(1)
63 cmd_id = m.group(2)
64 var_val = m.group(3)
65 if not interact_instance.keep_ids:
66 cmd_id = interact_instance.next_id
67 interact_instance.next_id += 1
68 next_step.command = '%s %s %s' % (set_get, cmd_id, var_val)
69
70 return next_step
71
72 def __init__(self, port, host, verbose=False, update=False, keep_ids=True):
73 if not update:
74 keep_ids = True
75 self.keep_ids = keep_ids
76 super().__init__(InteractCtrl.CtrlStep, port=port, host=host, verbose=verbose, update=update)
77
78 def connect(self):
79 self.next_id = 1
80 super().connect()
81
82 def send(self, data):
83 data = Ctrl().add_header(data)
84 return self.socket.send(data) == len(data)
85
86 def receive(self):
87 responses = []
88 data = self.socket.recv(4096)
89 while (len(data)>0):
90 (response_with_header, data) = IPA().split_combined(data)
91 response = Ctrl().rem_header(response_with_header)
92 responses.append(response.decode('utf-8'))
93 return responses
94
95 def command(self, command):
96 assert self.send(command)
97 res = self.receive()
98 split_responses = []
99 for r in res:
100 split_responses.extend(r.splitlines())
101 sys.stdout.flush()
102 sys.stderr.flush()
103 return split_responses
104
105if __name__ == '__main__':
106 parser = common_parser()
107 parser.add_argument('-i', '--keep-ids', dest='keep_ids', action='store_true',
108 help='With --update, default is to overwrite the command IDs'
109 ' so that they are consecutive numbers starting from 1.'
110 ' With --keep-ids, do not change these command IDs.')
111 args = parser.parse_args()
112
113 interact = InteractCtrl(args.port, args.host, args.verbose, args.update, args.keep_ids)
114
115 main(command_str=args.command_str,
116 transcript_files=args.transcript_files,
117 interact=interact,
118 verbose=args.verbose)
119
120# vim: tabstop=4 shiftwidth=4 expandtab nocin ai