configurationengine/doc/plugins/dev-plugin/example-plugin.rst
changeset 3 e7e0ae78773e
parent 0 2e8eeb919028
equal deleted inserted replaced
2:87cfa131b535 3:e7e0ae78773e
    10 - Plug-in structure:
    10 - Plug-in structure:
    11     - Reader class
    11     - Reader class
    12     - Implementation class
    12     - Implementation class
    13     - Implementation model
    13     - Implementation model
    14 - Using ``cone.public.utils`` for ConfML setting reference handling
    14 - Using ``cone.public.utils`` for ConfML setting reference handling
       
    15 - Providing XML schema validation and model-level validation
    15 - Unit tests:
    16 - Unit tests:
    16     - Testing the reader class, the implementation class and the model classes separately
    17     - Testing the reader class, the implementation class and the model classes separately
    17     - Output generation testing (plug-in scope integration test)
    18     - Output generation testing (plug-in scope integration test)
       
    19     - Validation testing
    18 
    20 
    19 The ExampleML language
    21 The ExampleML language
    20 ----------------------
    22 ----------------------
    21 
    23 
    22 The Implementation Markup Language in the example plug-in is ExampleML. The language
    24 The Implementation Markup Language in the example plug-in is ExampleML. The language
    53 - ``plugins/`` - Root directory for all ConE plug-in sources
    55 - ``plugins/`` - Root directory for all ConE plug-in sources
    54     - ``example/`` - Example plug-in package directory
    56     - ``example/`` - Example plug-in package directory
    55         - ``ConeExamplePlugin/`` - Source for the example plug-in
    57         - ``ConeExamplePlugin/`` - Source for the example plug-in
    56             - ``examplemlplugin/`` - Module directory containing all plug-in code
    58             - ``examplemlplugin/`` - Module directory containing all plug-in code
    57                 - ``tests/`` - Unit tests and test data for the plug-in
    59                 - ``tests/`` - Unit tests and test data for the plug-in
    58                     - ``project/`` - Configuration project used in the tests
    60                     - ``testdata/`` - Directory containing all test data needed by the test cases
    59                     - ``gen_expected/`` - Expected output for generation test case
       
    60                     - ``__init__.py`` - Test module initialization file
    61                     - ``__init__.py`` - Test module initialization file
    61                     - ``runtests.py`` - Script for running all test cases
    62                     - ``runtests.py`` - Script for running all test cases
    62                     - ``unittest_exampleml_impl.py`` - File containing test cases
    63                     - ``unittest_exampleml_impl.py`` - File containing test cases
    63                     - ``unittest_exampleml_reader.py`` - File containing test cases
    64                     - ``unittest_exampleml_reader.py`` - File containing test cases
    64                     - ``unittest_exampleml_generation.py`` - File containing test cases
    65                     - ``unittest_exampleml_generation.py`` - File containing test cases
       
    66                     - ``unittest_exampleml_validation.py`` - File containing test cases
       
    67                 - ``xsd/`` - XML Schema files for schema validation
       
    68                     - ``exampleml.xsd`` - Schema file for schema validation
    65                 - ``__init__.py`` - Plug-in module initialization file
    69                 - ``__init__.py`` - Plug-in module initialization file
    66                 - ``exampleml_impl.py`` - Plug-in source file
    70                 - ``exampleml_impl.py`` - Plug-in source file
    67                 - ``exampleml_reader.py`` - Plug-in source file
    71                 - ``exampleml_reader.py`` - Plug-in source file
       
    72                 - ``exampleml_validators.py`` - Plug-in source file
    68             - ``setup.py`` - Setup script for packaging the plug-in into an .egg file
    73             - ``setup.py`` - Setup script for packaging the plug-in into an .egg file
    69             - ``setup.cfg`` - Configuration file for ``setup.py``
    74             - ``setup.cfg`` - Configuration file for ``setup.py``
    70         - ``integration-test/`` - Integration tests for the example plug-in package
    75         - ``integration-test/`` - Integration tests for the example plug-in package
    71             - ``testdata/`` - Test data for the integration tests
    76             - ``testdata/`` - Test data for the integration tests
    72             - ``__init__.py`` - Test module initialization file
    77             - ``__init__.py`` - Test module initialization file
    81 
    86 
    82 - *Implementation model*, represents the logical model of the implementation specified in the XML data
    87 - *Implementation model*, represents the logical model of the implementation specified in the XML data
    83 - *Implementation class*, works as the interface of the plug-in towards ConE and uses the model to do the actual work
    88 - *Implementation class*, works as the interface of the plug-in towards ConE and uses the model to do the actual work
    84 - *Implementation reader*, converts the XML data into the logical model and creates a new implementation class instance
    89 - *Implementation reader*, converts the XML data into the logical model and creates a new implementation class instance
    85 
    90 
    86 In this case the *model* consists just of the class Output, which corresponds to the ``<output>`` element.
    91 Here the *model* consists just of the class Output, which corresponds to the ``<output>`` element.
       
    92 
       
    93 In addition to these, there is a collection of *validator classes* that are
       
    94 responsible for handling model-level validation.
    87 
    95 
    88 Plug-in code
    96 Plug-in code
    89 ------------
    97 ------------
    90 
    98 
    91 exampleml_model.py
    99 exampleml_model.py
   133 own method. Again, this is to make unit testing easier.
   141 own method. Again, this is to make unit testing easier.
   134 
   142 
   135 .. literalinclude:: /../source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_reader.py
   143 .. literalinclude:: /../source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_reader.py
   136    :linenos:
   144    :linenos:
   137 
   145 
       
   146 Note that the reader class provides the XML schema by overriding
       
   147 ``get_schema_data()``. If this method was not overridden, a default schema
       
   148 that accepts (almost) anything would be used for schema validation.
       
   149 
       
   150 
       
   151 exampleml_validators.py
       
   152 ...................
       
   153 
       
   154 This file defines all validator classes. Since ExampleML is so simple, there
       
   155 are only two cases that need to be validated on the model level: setting
       
   156 references and the encoding. Notice that the setting reference validator
       
   157 uses the method ``check_feature_reference()`` inherited from ``ImplValidatorBase``.
       
   158 As there are utility functions for handling references in a uniform way, there
       
   159 is also a utility function for validating them.
       
   160 
       
   161 Note also the class list VALIDATOR_CLASSES at the bottom, which contains both
       
   162 of the validator classes. The file ``setup.py`` contains an entry point
       
   163 definition that points to this list, and the validation framework finds the
       
   164 validators via that.
       
   165 
       
   166 .. literalinclude:: /../source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_validators.py
       
   167    :linenos:
   138 
   168 
   139 Unit tests
   169 Unit tests
   140 ----------
   170 ----------
   141 
   171 
   142 Due to the dynamic nature of Python, an extensive set of unit tests is required for every plug-in.
   172 Due to the dynamic nature of Python, an extensive set of unit tests is required for every plug-in.
   202 the workding copy.
   232 the workding copy.
   203 
   233 
   204 .. literalinclude:: /../source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_generation.py
   234 .. literalinclude:: /../source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_generation.py
   205    :linenos:
   235    :linenos:
   206 
   236 
       
   237 unittest_exampleml_validation.py
       
   238 ................................
       
   239 
       
   240 Like ``unittest_exampleml_generation.py`` test output generation, this file
       
   241 tests validation. The test cases themselves are pretty simple, since there are
       
   242 pre-existing helper methods for running the tests, and the tests mainly consist
       
   243 of test data and expected.
       
   244 
       
   245 .. literalinclude:: /../source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_validation.py
       
   246    :linenos:
       
   247 
       
   248    
   207 Plug-in packaging
   249 Plug-in packaging
   208 -----------------
   250 -----------------
   209 
   251 
   210 The file ``setup.py`` handles the packaging of the plug-in into an egg file.
   252 The file ``setup.py`` handles the packaging of the plug-in into an egg file.
   211 
   253 
   212 The most important thing here is the plug-in's entry point info. The
   254 The most important thing here is the plug-in's entry point info. The
   213 plug-in's reader classes must be specified as entry points, or they won't be
   255 plug-in's reader and validator classes must be specified as entry points,
   214 loaded.
   256 or they won't be loaded.
   215 
   257 
   216 .. literalinclude:: /../source/plugins/example/ConeExamplePlugin/setup.py
   258 .. literalinclude:: /../source/plugins/example/ConeExamplePlugin/setup.py
   217    :linenos:
   259    :linenos:
   218 
   260 
   219 
   261 
   266 ....................
   308 ....................
   267 
   309 
   268 This file contains tests for generating output using the example plug-in.
   310 This file contains tests for generating output using the example plug-in.
   269 Note the following things:
   311 Note the following things:
   270 
   312 
   271 - The use of the variable ``CONE_CMD`` in ``get_cmd()``. This variable is set to
   313 - The check if ``CONE_CMD`` is in the environment variables in ``get_cmd()``.
   272   contain the actual ConE command to run if the tests are being run from the
   314   This variable is set to contain the actual ConE command to run if the tests
   273   exported standalone test set. In practice this will be something like
   315   are being run from the exported standalone test set. In practice this will be
   274   ``C:/cone_test/cone/cone.cmd``.
   316   something like  ``C:/cone_test/cone/cone.cmd``.
   275 - The actual generation and testing is done in a separate function, ``run_test_generate()``,
   317 - The actual generation and testing is done in a separate function, ``_run_test_generate()``,
   276   and there are two actual test functions that call it. One runs the test directly on the
   318   and there are two actual test functions that call it. One runs the test directly on the
   277   test project on the file system, and another first zips the test project and then runs
   319   test project on the file system, and another first zips the test project and then runs
   278   the test on that. It is a good idea to test that generation works the same in both cases,
   320   the test on that. It is a good idea to test that generation works the same in both cases,
   279   since it can be easy to forget to take into account generation from a ZIP file when creating
   321   since it can be easy to forget to take into account generation from a ZIP file when creating
   280   a plug-in (e.g. using ``shutil`` functions to perform copy operations when the ConE API
   322   a plug-in (e.g. using ``shutil`` functions to perform copy operations when the ConE API