For Developers

In this section we give some tips and guidelines for developing and contributing code to FRESCO.

Directory Structure

The FRESCO root directory (see https://github.com/aicis/fresco) contains a number sub-directories containing multiple sub-projects for FRESCO. Here we describe the most important directories:

  • core - contains the core FRESCO framework including the application interface, library of generic functionality and dummy suites.
  • demos - contains a number of demos demonstrating how FRESCO can be used. Each demo has its own sub-project.
  • doc - contains the source of the documentation for this site.
  • suite - contains the protocol suites implemented in FRESCO each as its own sub-project.
  • tools - contains various tools used in FRESCO each as its own sub-project.

We use Maven to manage FRESCO, and within each sub-project we use the standard Maven directory structure.

Developing using an IDE

The FRESCO team (mostly) uses Eclipse to develop FRESCO. To develop using Eclipse, first check out a fork of FRESCO from GitHub. Then to import FRESCO into Eclipse choose

File > Import... > Maven > Existing Maven Projects

and select the FRESCO root directory.

To help conform to the code style used in FRESCO, as described in the Code Style section, we recommend installing the Checkstyle plugin for Eclipse and configuring it to use the Google style. This plugin can also be used to generate a code formatter for Eclipse. To ensure imports are ordered correctly, you may also need to go to

Eclipse > Preferences... > Java > Code Style > Organize Imports

and delete all groups in the list displayed (as the Google style dictates that all imports must be in a single block).

To help fulfill the code coverage goal described in Testing we also recommend installing the Jacoco plugin. This eases checking code coverage on your changes locally.

Alternatively some IntelliJ support is also present - look for the .idea files in the root of the repository.

Code Style

To keep the code style consistent we use the style defined by Google. We prefer to keep the code from generating compile warnings, using the @SuppressWarnings annotation sparingly in case of unavoidable warnings.

Testing

We use JUnit4 for testing. We use the Travis tool to continuously check that all code committed to the repository compiles and passes all tests. We strive for 100% test coverage of the FRESCO code and use the Codecov tool to automatically check that new patches have 100% coverage and do not decrease the overall test coverage.

For each sub-project tests are located in the source code folder named test separated from the main code, as per the standard Maven directory structure. When writing tests for something in package x.y.z the test should belong to the same package. This way, methods that are package private and therefore not exposed in the FRESCO API can also be tested.

We work with two classes of tests:

  • Regular tests. These should be fast and not rely on any external dependencies such as a server already running. I.e., it should always possible to check out the code and just run these tests with only meeting the requirements seen in the install section.

  • Integration tests. These are tests that for example rely on external databases being set up, or involve deployment to different hosts. You can mark a test class or test method as integration test by using the @Category annotation like so:

    @Test @Category(IntegrationTest.class) public void testSomething() { // Your test goes here. }
    

Integration tests are ignored when you the FRESCO tests suite using the Maven command

mvn test

but are included when you run

mvn integration-test

A few good practices regarding tests:

  1. Write tests.
  2. Don’t delete, comment, or @Ignore tests unless you really know what you are doing.
  3. Make sure that tests are independent of each other.
  4. Tests should be deterministic. Use a pseudo-random generator with a fixed seed if you need randomness.
  5. Working tests should be silent when they work. Use log level Level.FINE if needed.

Writing Tests for a Protocol Suite

If you are developing a new protocol suite you may want to write tests in the same way as the tests for suites that are already included in FRESCO. Consider, e.g., the SPDZ suite. A helper method is made:

protected void runTest(TestThreadRunner.TestThreadFactory f, EvaluationStrategy evalStrategy,
      NetworkingStrategy network, PreprocessingStrategy preProStrat, int noOfParties) throws Exception

The first argument to runTest is a TestThreadFactory which defines which logic should be tested. It is a factory that provides threads for each party in the test. If the protocol to test is symmetric, each thread is identical. The test framework makes sure that each thread has access to its own partyId so if the test requires the parties to do different things, they can branch on their partyId.

The rest of the arguments to runTest are parameters over which you want your tests to vary. For example this could be the number of players and evaluation strategy. But it can also include parameters specific to your suite. The runTest should set up the remaining parameters for your test – those parameters that should remain fixed in all your tests.

Then create a number of small tests, like the following:

@Test
public void test_MultAndAdd_Sequential() throws Exception {
  runTest(new BasicArithmeticTests.TestSimpleMultAndAdd(), EvaluationStrategy.SEQUENTIAL,
    NetworkingStrategy.KRYONET, PreprocessingStrategy.DUMMY, 2);
  }

It is fine to let the name reflect the specific parameters used in the test. Note how we use a generic test here: The test BasicArithmeticTests.TestSimpleMultAndAdd can be used to test multiplications and additions for any protocol suite that supports basic arithmetic operations, so there is no need to rewrite such tests. Only write your own specific tests if you need to test some specific functionality of your suite that no other suite has, otherwise consider making the test generic such that it can be reused by others.

Writing many small tests like this makes it easy to decide later which of the tests to include. The “unit” test suite should be relatively quick and not require external setup. If it depends on such things, mark it with @Category(IntegrationTest.class).

Building the Documentation

The documentation will be built automatically and uploaded to fresco.readthedocs.org when new changes are pushed to the repository. Before committing changes to the documentation, it is a good idea to build the documentation locally and check that it looks ok. This can be done as follows.

Building the docs requires Sphinx to be installed. A good way to do this is by using virtualenv. Using virtualenv installs Sphinx in a local folder that can be easily removed, and it ensures that the installation does not have any side effects: Go to the doc folder. Then create a new virtual environment:

virtualenv env
source ./env/bin/activate
pip install -r requirements.txt

If the install fails, you might have to update pip. Just follow the directions pip gives you. This only needs to be done once. When done, you can activate the virtual environment just by doing:

source ./env/bin/activate

Once activated, you can build documentation with:

make html

On Mac OS X you may need to set the following environment variables:

export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8

You can enter the two lines directly in your terminal or to add them to your ~/.bash_profile.

Once built, you can view the result, open the file doc/build/html/index.hmtl with a web browser.