from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import os
import unittest
import onnx.backend.base
import onnx.backend.test

from onnx.backend.base import Device, DeviceType
from onnx.backend.test.runner import BackendIsNotSupposedToImplementIt
import onnx.shape_inference
from typing import Optional, Text, Any, Tuple, Sequence
from onnx import NodeProto, ModelProto
import numpy  # type: ignore

# The following just executes the fake backend through the backend test
# infrastructure. Since we don't have full reference implementation of all ops
# in ONNX repo, it's impossible to produce the proper results. However, we can
# run 'checker' (that's what base Backend class does) to verify that all tests
# fed are actually well-formed ONNX models.
#
# If everything is fine, all the tests would be marked as "skipped".
#
# We don't enable report in this test because the report collection logic itself
# fails when models are mal-formed.


class DummyBackend(onnx.backend.base.Backend):
    @classmethod
    def prepare(cls,
                model,  # type: ModelProto
                device='CPU',  # type: Text
                **kwargs  # type: Any
                ):  # type: (...) -> Optional[onnx.backend.base.BackendRep]
        super(DummyBackend, cls).prepare(model, device, **kwargs)

        # test shape inference
        onnx.shape_inference.infer_shapes(model)

        raise BackendIsNotSupposedToImplementIt(
            "This is the dummy backend test that doesn't verify the results but does run the checker")

    @classmethod
    def run_node(cls,
                 node,  # type: NodeProto
                 inputs,  # type: Any
                 device='CPU',  # type: Text
                 outputs_info=None,  # type: Optional[Sequence[Tuple[numpy.dtype, Tuple[int, ...]]]]
                 **kwargs  # type: Any
                 ):  # type: (...) -> Optional[Tuple[Any, ...]]
        super(DummyBackend, cls).run_node(node, inputs, device=device, outputs_info=outputs_info)
        raise BackendIsNotSupposedToImplementIt(
            "This is the dummy backend test that doesn't verify the results but does run the checker")

    @classmethod
    def supports_device(cls, device):
        d = Device(device)
        if d.type == DeviceType.CPU:
            return True
        return False


backend_test = onnx.backend.test.BackendTest(DummyBackend, __name__)
if os.getenv('APPVEYOR'):
    backend_test.exclude(r'(test_vgg19|test_zfnet)')

# import all test cases at global scope to make them visible to python.unittest
globals().update(backend_test
                 .test_cases)

if __name__ == '__main__':
    unittest.main()

@@ -143,16 +143,33 @@
 terals%0A%0A
+import itertools%0A
 import o
@@ -170,16 +170,16 @@
 port os%0A
-
 import u
@@ -479,16 +479,29 @@
 delProto
+, TensorProto
 %0Aimport 
@@ -1459,16 +1459,24 @@
 %0A       
+ model =
  onnx.sh
@@ -1508,16 +1508,662 @@
 s(model)
+%0A        value_infos = %7Bvi.name: vi for vi in itertools.chain(model.graph.value_info, model.graph.output)%7D%0A%0A        if do_enforce_shape_inference_coverage(model):%0A            for node in model.graph.node:%0A                for i, output in enumerate(node.output):%0A                    if node.op_type == 'Dropout' and i != 0:%0A                        continue%0A                    assert output in value_infos%0A                    tt = value_infos%5Boutput%5D.type.tensor_type%0A                    assert tt.elem_type != TensorProto.UNDEFINED%0A                    for dim in tt.shape.dim:%0A                        assert dim.WhichOneof('value') == 'dim_value'
 %0A%0A      
@@ -3071,16 +3071,16 @@
 rn True%0A
-
         
@@ -3094,16 +3094,459 @@
 False%0A%0A%0A
+shape_coverage_whitelist = set(%0A    %5B'bvlc_alexnet', 'densenet121', 'inception_v1', 'inception_v2',%0A     'resnet50', 'shufflenet', 'SingleRelu', 'squeezenet_old', 'vgg19', 'zfnet'%5D)%0A%0A%0Adef do_enforce_shape_inference_coverage(model):%0A    if model.graph.name not in shape_coverage_whitelist:%0A        return False%0A    for node in model.graph.node:%0A        if node.op_type in set(%5B'RNN', 'LSTM', 'GRU'%5D):%0A            return False%0A    return True%0A%0A%0A
 backend_

add more shape inference tests (#971)