parent
aa2ac59b5c
commit
fee91b49ff
6 changed files with 315 additions and 22 deletions
@ -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 |
||||
|
Loading…
Reference in new issue