aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/core/end2end/tests/generate.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/core/end2end/tests/generate.py')
-rwxr-xr-xtest/core/end2end/tests/generate.py191
1 files changed, 191 insertions, 0 deletions
diff --git a/test/core/end2end/tests/generate.py b/test/core/end2end/tests/generate.py
new file mode 100755
index 0000000000..c7cb1f8f9e
--- /dev/null
+++ b/test/core/end2end/tests/generate.py
@@ -0,0 +1,191 @@
+#!/usr/bin/python2.7
+
+from copy import deepcopy
+
+def create(state, name):
+ me = getattr(state, name)
+ if not me.created:
+ new = me.copy()
+ new.created = True
+ cg = state.codegen.copy()
+ cg.lines.extend([
+ 'config.init_%s(f, %s_args)' % (name, name)])
+ s = State(state.client, state.server, cg)
+ setattr(s, name, new)
+ yield s
+
+def start_client(state):
+ if state.client.created and not state.client.started:
+ cg = state.codegen.copy()
+ cg.lines.extend([
+ 'client_call = grpc_channel_create_call(f.client, f.client_cq, "/foo", "test.google.com", deadline);'
+ ])
+ client = state.client.copy()
+ client.started = True
+ yield State(client, state.server, cg)
+
+def request_server(state):
+ if state.server.created and not state.server.requested:
+ cg = state.codegen.copy()
+ tag = cg.make_tag('request_server')
+ cg.lines.extend([
+ 'GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &server_call, &call_details, &request_metadata_recv, f.server_cq, tag(%d)))' % tag])
+ server = state.server.copy()
+ server.requested = True
+ yield State(state.client, server, cg)
+
+def start_op(state, l, r):
+ local = getattr(state, l)
+ remote = getattr(state, r)
+ if not local.started:
+ return
+ for send_initial_metadata in [True, False]:
+ for send_message in [True, False]:
+ for send_close in [True, False]:
+ for receive_initial_metadata in [True, False]:
+ for receive_message in [True, False]:
+ for receive_close in [True, False]:
+ if ((not send_initial_metadata) and (not send_message) and (not send_close) and
+ (not receive_initial_metadata) and (not receive_message) and (not receive_close)):
+ continue
+ if local.sending_initial_metadata and send_initial_metadata: continue
+ if local.sending_message and send_message: continue
+ if local.sending_close and send_close: continue
+ if l == 'server' and receive_initial_metadata: continue
+ if local.receiving_initial_metadata and receive_initial_metadata: continue
+ if local.receiving_message and receive_message: continue
+ if local.receiving_close and receive_close: continue
+ local2 = local.copy()
+ cg = state.codegen.copy()
+ cg.lines.extend(['op = ops']);
+ tag = cg.make_tag('start_op_%s' % l)
+ if send_initial_metadata:
+ cg.lines.extend([
+ 'op->type = GRPC_OP_SEND_INITIAL_METADATA;',
+ 'op->data.send_initial_metadata.count = 0;',
+ 'op++;'])
+ local2.sending_initial_metadata = tag
+ if send_message:
+ cg.lines.extend([
+ 'op->type = GRPC_OP_SEND_MESSAGE;',
+ 'op->data.send_message = %s_payload;' % l,
+ 'op++;'])
+ local2.sending_message = tag
+ if send_close:
+ if l == 'client':
+ cg.lines.extend([
+ 'op->type = GRPC_OP_SEND_CLOSE_FROM_CLIENT;',
+ 'op++'])
+ else:
+ cg.lines.extend([
+ 'op->type = GRPC_OP_SEND_STATUS_FROM_SERVER;',
+ 'op++'])
+ local2.sending_close = tag
+ if receive_initial_metadata:
+ cg.lines.extend([
+ 'op->type = GRPC_OP_RECV_INITIAL_METADATA;',
+ 'op++'])
+ local2.receiving_initial_metadata = tag
+ if receive_message:
+ cg.lines.extend([
+ 'op->type = GRPC_OP_RECV_MESSAGE;',
+ 'op++'])
+ local2.receiving_message = tag
+ if receive_close:
+ if l == 'client':
+ cg.lines.extend([
+ 'op->type = GRPC_OP_RECV_STATUS_ON_CLIENT;',
+ 'op++'])
+ else:
+ cg.lines.extend([
+ 'op->type = GRPC_OP_RECV_CLOSE_ON_SERVER;',
+ 'op++'])
+ local2.receiving_close = tag
+ cg.lines.extend([
+ 'GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(%s_call, ops, op - ops, tag(%d)));' % (l, tag)])
+ s = State(state.client, state.server, cg)
+ setattr(s, l, local2)
+ yield s
+
+def wrap(f, *a):
+ def g(state):
+ for x in f(state, *a):
+ yield x
+ return g
+
+MUTATORS = [
+ wrap(create, 'client'),
+ wrap(create, 'server'),
+ wrap(start_op, 'client', 'server'),
+ wrap(start_op, 'server', 'client'),
+ start_client,
+ request_server,
+ ]
+
+class Codegen(object):
+ lines = []
+ next_tag = 1
+ last_tag_creator = 'nobody'
+ def generate(self):
+ print '{'
+ print '\n'.join(self.lines)
+ print '}'
+ def copy(self):
+ cg = deepcopy(self)
+ cg.lines = self.lines[:]
+ return cg
+ def make_tag(self, name):
+ self.last_tag_creator = name
+ tag = self.next_tag
+ self.next_tag += 1
+ return tag
+
+class Endpoint(object):
+ created = False
+ started = False
+ requested = False
+ sent_initial_metadata = False
+ sent_messages = 0
+ sent_close = False
+ sending_initial_metadata = False
+ sending_message = False
+ sending_close = False
+ received_initial_metadata = False
+ received_messages = 0
+ received_close = False
+ receiving_initial_metadata = False
+ receiving_message = False
+ receiving_close = False
+
+ def copy(self):
+ return deepcopy(self)
+
+class State(object):
+ def __init__(self, client, server, codegen):
+ self.client = client
+ self.server = server
+ self.codegen = codegen
+
+ def as_dict(self):
+ return {'client': self.client.as_dict(), 'server': self.server.as_dict()}
+
+ def mutations(self):
+ for mutator in MUTATORS:
+ for new_state in mutator(self):
+ yield new_state
+
+count = 0
+def generate(state, depth):
+ global count
+ n = 0
+ #print ' '*depth, state.as_dict()
+ for state2 in state.mutations():
+ n += 1
+ generate(state2, depth+1)
+ if n == 0:
+ count += 1
+ #state.codegen.generate()
+
+generate(State(Endpoint(), Endpoint(), Codegen()), 0)
+print count
+