Esempio n. 1
0
    def test_dupe_abs_req_no_acc(self):
        """Test negotiation with duplicate requestor, no acceptor contexts."""
        context_a = PresentationContext()
        context_a.context_id = 1
        context_a.abstract_syntax = '1.2.840.10008.5.1.4.1.1.2'
        context_a.transfer_syntax = ['1.2.840.10008.1.2']

        context_b = PresentationContext()
        context_b.context_id = 3
        context_b.abstract_syntax = '1.2.840.10008.5.1.4.1.1.2'
        context_b.transfer_syntax = ['1.2.840.10008.1.2.1']

        context_c = PresentationContext()
        context_c.context_id = 5
        context_c.abstract_syntax = '1.2.840.10008.5.1.4.1.1.2'
        context_c.transfer_syntax = ['1.2.840.10008.1.2.2']

        rq_contexts = [context_a, context_b, context_c]
        acc_contexts = self.test_acc(rq_contexts, [])

        for context in acc_contexts:
            context._abstract_syntax = None

        result = self.test_func(rq_contexts, acc_contexts)

        assert len(result) == 3
        for context in result:
            assert context.context_id in [1, 3, 5]
            assert context.abstract_syntax == '1.2.840.10008.5.1.4.1.1.2'
            assert context.result == 0x03
Esempio n. 2
0
    def test_dupe_abs_req(self):
        """Test negotiation with duplicate requestor, no acceptor contexts."""
        context_a = PresentationContext()
        context_a.context_id = 1
        context_a.abstract_syntax = '1.2.840.10008.5.1.4.1.1.2'
        context_a.transfer_syntax = ['1.2.840.10008.1.2']

        context_b = PresentationContext()
        context_b.context_id = 3
        context_b.abstract_syntax = '1.2.840.10008.5.1.4.1.1.2'
        context_b.transfer_syntax = ['1.2.840.10008.1.2.1']

        context_c = PresentationContext()
        context_c.context_id = 5
        context_c.abstract_syntax = '1.2.840.10008.5.1.4.1.1.2'
        context_c.transfer_syntax = ['1.2.840.10008.1.2.2']

        t_syntax = [
            '1.2.840.10008.1.2', '1.2.840.10008.1.2.1', '1.2.840.10008.1.2.2'
        ]
        context_d = PresentationContext()
        context_d.abstract_syntax = '1.2.840.10008.5.1.4.1.1.2'
        context_d.transfer_syntax = t_syntax
        context_list = [context_a, context_b, context_c]
        result = self.test_func(context_list, [context_d])
        assert len(result) == 3
        for ii, context in enumerate(result):
            assert context.context_id in [1, 3, 5]
            assert context.abstract_syntax == '1.2.840.10008.5.1.4.1.1.2'
            assert context.result == 0x00
            assert context.transfer_syntax == [t_syntax[ii]]
Esempio n. 3
0
    def test_one_req_one_acc_accept_trans_diff(self):
        """Test negotiation one req/acc, matching accepted, multi trans."""
        context_a = PresentationContext()
        context_a.context_id = 1
        context_a.abstract_syntax = '1.2.840.10008.5.1.4.1.1.2'
        context_a.transfer_syntax = [
            '1.2.840.10008.1.2', '1.2.840.10008.1.2.1', '1.2.840.10008.1.2.2'
        ]
        context_b = PresentationContext()
        context_b.abstract_syntax = '1.2.840.10008.5.1.4.1.1.2'
        context_b.transfer_syntax = ['1.2.840.10008.1.2.2']
        rq_contexts = [context_a]
        acc_contexts = self.test_acc(rq_contexts, [context_b])

        for context in acc_contexts:
            context._abstract_syntax = None

        result = self.test_func(rq_contexts, acc_contexts)

        assert len(result) == 1
        context = result[0]
        assert context.context_id == 1
        assert context.abstract_syntax == '1.2.840.10008.5.1.4.1.1.2'
        assert context.result == 0x00
        assert context.transfer_syntax == ['1.2.840.10008.1.2.2']
Esempio n. 4
0
 def test_abstract_syntax(self):
     """Test abstract syntax setter"""
     pc = PresentationContext()
     pc.context_id = 1
     pc.abstract_syntax = '1.1.1'
     assert pc.abstract_syntax == UID('1.1.1')
     assert isinstance(pc.abstract_syntax, UID)
     pc.abstract_syntax = b'1.2.1'
     assert pc.abstract_syntax == UID('1.2.1')
     assert isinstance(pc.abstract_syntax, UID)
     pc.abstract_syntax = UID('1.3.1')
     assert pc.abstract_syntax == UID('1.3.1')
     assert isinstance(pc.abstract_syntax, UID)
Esempio n. 5
0
 def test_private_transfer_syntax(self):
     """Test negotiation with private transfer syntax"""
     context_a = PresentationContext()
     context_a.context_id = 1
     context_a.abstract_syntax = '1.2.840.10008.5.1.4.1.1.2'
     context_a.transfer_syntax = ['1.2.3.4']
     context_b = PresentationContext()
     context_b.abstract_syntax = '1.2.840.10008.5.1.4.1.1.2'
     context_b.transfer_syntax = ['1.2.840.10008.1.2.1', '1.2.3.4']
     result = self.test_func([context_a], [context_b])
     assert len(result) == 1
     context = result[0]
     assert context.context_id == 1
     assert context.abstract_syntax == '1.2.840.10008.5.1.4.1.1.2'
     assert context.result == 0x00
     assert context.transfer_syntax == ['1.2.3.4']
Esempio n. 6
0
 def test_one_req_one_acc_mismatch(self):
     """Test negotiation one req/acc, mismatched rejected"""
     context_a = PresentationContext()
     context_a.context_id = 1
     context_a.abstract_syntax = '1.2.840.10008.5.1.4.1.1.2'
     context_a.transfer_syntax = [
         '1.2.840.10008.1.2', '1.2.840.10008.1.2.1'
     ]
     context_b = PresentationContext()
     context_b.abstract_syntax = '1.2.840.10008.5.1.4.1.1.4'
     context_b.transfer_syntax = ['1.2.840.10008.1.2.2']
     result = self.test_func([context_a], [context_b])
     assert len(result) == 1
     context = result[0]
     assert context.context_id == 1
     assert context.abstract_syntax == '1.2.840.10008.5.1.4.1.1.2'
     assert context.result == 0x03
Esempio n. 7
0
 def test_no_req_one_acc(self):
     """Test negotiation with no requestor, one acceptor contexts."""
     context = PresentationContext()
     context.context_id = 1
     context.abstract_syntax = '1.2.840.10008.5.1.4.1.1.2'
     context.transfer_syntax = ['1.2.840.10008.1.2']
     result = self.test_func([], [context])
     assert result == []
Esempio n. 8
0
 def test_no_req_one_acc_raise(self):
     """Test negotiation with no requestor, one acceptor contexts."""
     context = PresentationContext()
     context.context_id = 1
     context.abstract_syntax = '1.2.840.10008.5.1.4.1.1.2'
     context.transfer_syntax = ['1.2.840.10008.1.2']
     with pytest.raises(ValueError):
         result = self.test_func([], [context])
Esempio n. 9
0
    def test_abstract_syntax_nonconformant(self, caplog):
        """Test adding non-conformant abstract syntaxes"""
        caplog.set_level(logging.DEBUG, logger='pynetdicom3.presentation')
        pc = PresentationContext()
        pc.context_id = 1
        pc.abstract_syntax = UID('1.4.1.')
        assert pc.abstract_syntax == UID('1.4.1.')
        assert isinstance(pc.abstract_syntax, UID)

        assert ("'abstract_syntax' set to a non-conformant UID" in caplog.text)
Esempio n. 10
0
    def test_typical(self):
        """Test a typical set of presentation context negotiations."""
        req_contexts = []
        for ii, context in enumerate(StoragePresentationContexts):
            pc = PresentationContext()
            pc.context_id = ii * 2 + 1
            pc.abstract_syntax = context.abstract_syntax
            pc.transfer_syntax = [
                '1.2.840.10008.1.2', '1.2.840.10008.1.2.1',
                '1.2.840.10008.1.2.2'
            ]
            req_contexts.append(pc)

        acc_contexts = []
        for uid in UID_dictionary:
            pc = PresentationContext()
            pc.abstract_syntax = uid
            pc.transfer_syntax = [
                '1.2.840.10008.1.2', '1.2.840.10008.1.2.1',
                '1.2.840.10008.1.2.2'
            ]
            acc_contexts.append(pc)

        acc_contexts = self.test_acc(req_contexts, acc_contexts)

        for context in acc_contexts:
            context._abstract_syntax = None

        results = self.test_func(req_contexts, acc_contexts)

        assert len(results) == len(req_contexts)
        for ii, context in enumerate(req_contexts):
            assert results[ii].context_id == context.context_id
            assert results[ii].abstract_syntax == context.abstract_syntax
            if results[
                    ii].abstract_syntax == '1.2.840.10008.5.1.4.1.1.1.1.1.1':
                assert results[ii].result == 0x03
            elif results[
                    ii].abstract_syntax == '1.2.840.10008.5.1.1.4.1.1.3.1':
                assert results[ii].result == 0x03
            else:
                assert results[ii].result == 0x00
                assert results[ii].transfer_syntax == ['1.2.840.10008.1.2']
Esempio n. 11
0
    def test_tuple(self):
        """Test the .as_tuple"""
        context = PresentationContext()
        context.context_id = 3
        context.abstract_syntax = '1.2.840.10008.1.1'
        context.transfer_syntax = ['1.2.840.10008.1.2']
        out = context.as_tuple

        assert out.context_id == 3
        assert out.abstract_syntax == '1.2.840.10008.1.1'
        assert out.transfer_syntax == '1.2.840.10008.1.2'
Esempio n. 12
0
 def test_string_output(self):
     """Test string output"""
     pc = PresentationContext()
     pc.context_id = 1
     pc.abstract_syntax = '1.1.1'
     pc.transfer_syntax = ['1.2.840.10008.1.2', '1.2.3']
     pc._scp_role = True
     pc._scu_role = False
     pc.result = 0x02
     assert '1.1.1' in pc.__str__()
     assert 'Implicit' in pc.__str__()
     assert 'Provider Rejected' in pc.__str__()
Esempio n. 13
0
 def test_one_req_one_acc_match(self):
     """Test negotiation one req/acc, matching accepted."""
     context = PresentationContext()
     context.context_id = 1
     context.abstract_syntax = '1.2.840.10008.5.1.4.1.1.2'
     context.transfer_syntax = ['1.2.840.10008.1.2']
     result = self.test_func([context], [context])
     assert len(result) == 1
     context = result[0]
     assert context.context_id == 1
     assert context.abstract_syntax == '1.2.840.10008.5.1.4.1.1.2'
     assert context.result == 0x00
     assert context.transfer_syntax == ['1.2.840.10008.1.2']
Esempio n. 14
0
 def test_setter(self, good_init):
     """Test the presentation context class init"""
     (context_id, abs_syn, tran_syn) = good_init
     pc = PresentationContext()
     pc.context_id = context_id
     pc.abstract_syntax = abs_syn
     pc.transfer_syntax = tran_syn
     assert pc.context_id == context_id
     assert pc.abstract_syntax == abs_syn
     assert pc.transfer_syntax == tran_syn
     assert pc._scu_role is None
     assert pc._scp_role is None
     assert pc.result is None
Esempio n. 15
0
 def test_equality(self):
     """Test presentation context equality"""
     pc_a = PresentationContext()
     pc_a.context_id = 1
     pc_a.abstract_syntax = '1.1.1'
     pc_a.transfer_syntax = ['1.2.840.10008.1.2']
     pc_b = PresentationContext()
     pc_b.context_id = 1
     pc_b.abstract_syntax = '1.1.1'
     pc_b.transfer_syntax = ['1.2.840.10008.1.2']
     assert pc_a == pc_a
     assert pc_a == pc_b
     assert not pc_a != pc_b
     assert not pc_a != pc_a
     pc_a._scp_role = True
     assert not pc_a == pc_b
     pc_b._scp_role = True
     assert pc_a == pc_b
     pc_a._scu_role = True
     assert not pc_a == pc_b
     pc_b._scu_role = True
     assert pc_a == pc_b
     assert not 'a' == pc_b
Esempio n. 16
0
    def test_private_abstract_syntax(self):
        """Test negotiation with private abstract syntax"""
        context_a = PresentationContext()
        context_a.context_id = 1
        context_a.abstract_syntax = '1.2.3.4'
        context_a.transfer_syntax = ['1.2.840.10008.1.2.1']
        context_b = PresentationContext()
        context_b.abstract_syntax = '1.2.3.4'
        context_b.transfer_syntax = ['1.2.840.10008.1.2.1']
        rq_contexts = [context_a]
        acc_contexts = self.test_acc(rq_contexts, [context_b])

        for context in acc_contexts:
            context._abstract_syntax = None

        result = self.test_func(rq_contexts, acc_contexts)

        assert len(result) == 1
        context = result[0]
        assert context.context_id == 1
        assert context.abstract_syntax == '1.2.3.4'
        assert context.result == 0x00
        assert context.transfer_syntax == ['1.2.840.10008.1.2.1']
Esempio n. 17
0
    def test_one_req_no_acc(self):
        """Test negotiation with one requestor, no acceptor contexts."""
        context = PresentationContext()
        context.context_id = 1
        context.abstract_syntax = '1.2.840.10008.5.1.4.1.1.2'
        context.transfer_syntax = ['1.2.840.10008.1.2']
        result = self.test_func([context], [])

        assert len(result) == 1
        context = result[0]
        assert context.context_id == 1
        assert context.abstract_syntax == '1.2.840.10008.5.1.4.1.1.2'
        assert context.transfer_syntax[0] == '1.2.840.10008.1.2'
        assert len(context.transfer_syntax) == 1
        assert context.result == 0x02
    def test_conversion(self):
        """ Check conversion to a PDU produces the correct output """
        assoc = A_ASSOCIATE()
        assoc.application_context_name = "1.2.840.10008.3.1.1.1"
        assoc.calling_ae_title = 'ECHOSCU'
        assoc.called_ae_title = 'ANY-SCP'
        assoc.maximum_length_received = 16382
        assoc.implementation_class_uid = '1.2.826.0.1.3680043.9.3811.0.9.0'

        imp_ver_name = ImplementationVersionNameNotification()
        imp_ver_name.implementation_version_name = 'PYNETDICOM_090'
        assoc.user_information.append(imp_ver_name)

        pc = PresentationContext()
        pc.context_id = 1
        pc.abstract_syntax = '1.2.840.10008.1.1'
        pc.transfer_syntax = ['1.2.840.10008.1.2']
        assoc.presentation_context_definition_list = [pc]

        pdu = A_ASSOCIATE_RQ()
        pdu.from_primitive(assoc)
        data = pdu.encode()

        ref = b"\x01\x00\x00\x00\x00\xd1\x00\x01\x00\x00\x41\x4e\x59\x2d\x53\x43" \
              b"\x50\x20\x20\x20\x20\x20\x20\x20\x20\x20\x45\x43\x48\x4f\x53\x43" \
              b"\x55\x20\x20\x20\x20\x20\x20\x20\x20\x20\x00\x00\x00\x00\x00\x00" \
              b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
              b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x15\x31\x2e" \
              b"\x32\x2e\x38\x34\x30\x2e\x31\x30\x30\x30\x38\x2e\x33\x2e\x31\x2e" \
              b"\x31\x2e\x31\x20\x00\x00\x2e\x01\x00\x00\x00\x30\x00\x00\x11\x31" \
              b"\x2e\x32\x2e\x38\x34\x30\x2e\x31\x30\x30\x30\x38\x2e\x31\x2e\x31" \
              b"\x40\x00\x00\x11\x31\x2e\x32\x2e\x38\x34\x30\x2e\x31\x30\x30\x30" \
              b"\x38\x2e\x31\x2e\x32\x50\x00\x00\x3e\x51\x00\x00\x04\x00\x00\x3f" \
              b"\xfe\x52\x00\x00\x20\x31\x2e\x32\x2e\x38\x32\x36\x2e\x30\x2e\x31" \
              b"\x2e\x33\x36\x38\x30\x30\x34\x33\x2e\x39\x2e\x33\x38\x31\x31\x2e" \
              b"\x30\x2e\x39\x2e\x30\x55\x00\x00\x0e\x50\x59\x4e\x45\x54\x44\x49" \
              b"\x43\x4f\x4d\x5f\x30\x39\x30"

        assert data == ref
Esempio n. 19
0
 def test_abstract_syntax_raises(self):
     """Test exception raised if invalid abstract syntax"""
     pc = PresentationContext()
     with pytest.raises(TypeError):
         pc.abstract_syntax = 1234
Esempio n. 20
0
    def acceptor_contexts(self, contexts):
        """Set the Acceptor's presentation contexts.

        Must be a list of pynetdicom3.utils.PresentationContext
        There are two possible situations
          1. The local AE issues the request and receives the response
          2. The peer AE issues the request and the local must determine
           the response
        The first situation means that the acceptor has already decided on
          a Result and (if accepted) which Transfer Syntax to use
        The second situation means that we must determine whether to accept
          or reject presentation context and which Transfer Syntax to use

          requestor_contexts cannot be an empty list
        When the local AE is making the request, this is just the contents of
        the A-ASSOCIATE PresentationContextDefinitionResultList parameter
         (Result value will not be None)
        When the peer AE is making the request this will be the list of the
          SCP supported SOP classes combined with the supported Transfer
          Syntax(es) (Result value will be None)

        FIXME: This needs to be refactored, its slow and overly complex
        FIXME: It would be better to have a separate method to call when the
            user wants the contexts evaluated
        """
        if self.requestor_contexts == []:
            raise RuntimeError("You can only set the Acceptor's presentation "
                               "contexts after the Requestor's")

        if not isinstance(contexts, list):
            raise TypeError("acceptor_contexts must be a list of "
                            "PresentationContext items")

        # Validate the supplied contexts
        self._acceptor_contexts = []
        for ii in contexts:
            if isinstance(ii, PresentationContext):
                self._acceptor_contexts.append(ii)
            else:
                raise TypeError("acceptor_contexts must be a list of "
                                "PresentationContext items")

        # Generate accepted_contexts and rejected_contexts
        self.accepted = []
        self.rejected = []
        if self._acceptor_contexts != [] and self._requestor_contexts != []:
            # For each of the contexts available to the acceptor
            for ii_req in self._requestor_contexts:
                # Get the acceptor context with the same Abstract Syntax as
                #   the requestor context
                acc_context = None
                for ii_acc in self._acceptor_contexts:
                    # The acceptor context will only have an abstract syntax
                    #   if we are the Acceptor, otherwise we have to match
                    #   using the IDs

                    # If we are the Requestor then the Acceptor contexts
                    #   will have no Abstract Syntax
                    if ii_acc.abstract_syntax is not None:
                        if ii_acc.abstract_syntax == ii_req.abstract_syntax:
                            acc_context = ii_acc
                    else:
                        if ii_acc.context_id == ii_req.context_id:
                            acc_context = ii_acc
                            # Set Abstract Syntax (for convenience)
                            ii_acc.abstract_syntax = ii_req.abstract_syntax

                # Create a new PresentationContext item that will store the
                #   results from the negotiation
                result = PresentationContext()
                result.context_id = ii_req.context_id
                result.abstract_syntax = ii_req.abstract_syntax

                # If no matching Abstract Syntax then we are the Acceptor and
                #   we reject the current context (0x03 - abstract syntax not
                #   supported)
                if acc_context is None:
                    # FIXME: make pdu not require this.
                    result.transfer_syntax = [ii_req.transfer_syntax[0]]
                    result.result = 0x03
                    result = self.negotiate_scp_scu_role(ii_req, result)
                    self.rejected.append(result)

                # If there is a matching Abstract Syntax then check to see if
                #   the result is None (indicates we are the Acceptor) or
                #   has a value set (indicates we are the Requestor)
                else:
                    # We are the Acceptor and must decide to accept or reject
                    #   the context
                    if acc_context.result is None:

                        # Check the Transfer Syntaxes
                        #   We accept the first matching transfer syntax
                        for transfer_syntax in acc_context.transfer_syntax:
                            # The local transfer syntax is used in order to
                            #   enforce preference based on position
                            if transfer_syntax in ii_req.transfer_syntax:
                                result.transfer_syntax = [transfer_syntax]
                                result.result = 0x00
                                result = self.negotiate_scp_scu_role(
                                    ii_req, result)
                                self.accepted.append(result)
                                break

                        # Refuse sop class because TS not supported
                        else:
                            # FIXME: make pdu not require this.
                            result.transfer_syntax = [transfer_syntax]
                            result.result = 0x04
                            result = self.negotiate_scp_scu_role(
                                ii_req, result)
                            self.rejected.append(result)

                    # We are the Requestor and the Acceptor has accepted this
                    #   context
                    elif acc_context.result == 0x00:
                        # The accepted transfer syntax (there is only 1)
                        result.transfer_syntax = [
                            acc_context.transfer_syntax[0]
                        ]

                        # Add it to the list of accepted presentation contexts
                        self.accepted.append(result)

                    # We are the Requestor and the Acceptor has rejected this
                    #   context
                    elif acc_context.result in [0x01, 0x02, 0x03, 0x04]:
                        # The rejected transfer syntax(es)
                        result.transfer_syntax = acc_context.transfer_syntax

                        # Add it to the list of accepted presentation contexts
                        self.rejected.append(result)

                    else:
                        raise ValueError(
                            "Invalid 'Result' parameter in the "
                            "Acceptor's Presentation Context list")