All Projects → whitfin → Local Cluster

whitfin / Local Cluster

Licence: mit
Easy local cluster creation for Elixir to aid in unit testing

Programming Languages

elixir
2628 projects

Projects that are alternatives of or similar to Local Cluster

Datasplash
Clojure API for a more dynamic Google Dataflow
Stars: ✭ 111 (-21.83%)
Mutual labels:  distributed-computing
Test Smells
Test Smells for Android developers
Stars: ✭ 120 (-15.49%)
Mutual labels:  unit-testing
React Shopping Cart
🛍️ Simple ecommerce cart application built with React Redux
Stars: ✭ 1,808 (+1173.24%)
Mutual labels:  unit-testing
Sequelize Mock
A simple mock interface specifically for testing code relying on Sequelize models
Stars: ✭ 116 (-18.31%)
Mutual labels:  unit-testing
Rdfunit
An RDF Unit Testing Suite
Stars: ✭ 117 (-17.61%)
Mutual labels:  unit-testing
Openmole
Workflow engine for exploration of simulation models using high throughput computing
Stars: ✭ 120 (-15.49%)
Mutual labels:  distributed-computing
Spring Data Mock
Mock facility for Spring Data repositories
Stars: ✭ 110 (-22.54%)
Mutual labels:  unit-testing
Orleans.clustering.kubernetes
Orleans Membership provider for Kubernetes
Stars: ✭ 140 (-1.41%)
Mutual labels:  distributed-computing
Stryker4s
Mutation testing for Scala. Work in progress...
Stars: ✭ 118 (-16.9%)
Mutual labels:  unit-testing
Propertyfindar
🏘 🎃 Real Estate Sample App with RxJava3+Coroutines Flow, Dynamic Feature Modules, Dagger Hilt, Offline First, ConcatAdapter, Animations and tests for Room, Retrofit, useCase and ViewModels with TDD.
Stars: ✭ 133 (-6.34%)
Mutual labels:  unit-testing
Fakery
👽 Swift fake data generator
Stars: ✭ 1,572 (+1007.04%)
Mutual labels:  unit-testing
Movieapp
🎬 MovieApp is a Flutter application built to demonstrate the use of modern development tools with best practices implementation like Modularization, BLoC, Dependency Injection, Dynamic Theme, Cache, Shimmer, Testing, Flavor, CI/CD, etc.
Stars: ✭ 117 (-17.61%)
Mutual labels:  unit-testing
Deequ
Deequ is a library built on top of Apache Spark for defining "unit tests for data", which measure data quality in large datasets.
Stars: ✭ 2,020 (+1322.54%)
Mutual labels:  unit-testing
Test
The reference C++ unit testing framework (TDD, xUnit, C++03/11/14/17)
Stars: ✭ 112 (-21.13%)
Mutual labels:  unit-testing
Dotnetlabs
.NET Labs -- Show Me the Tips and Tricks and Code
Stars: ✭ 135 (-4.93%)
Mutual labels:  unit-testing
Elephas
Distributed Deep learning with Keras & Spark
Stars: ✭ 1,521 (+971.13%)
Mutual labels:  distributed-computing
Scalecube Cluster
ScaleCube Cluster is a lightweight Java VM implementation of SWIM: Scalable Weakly-consistent Infection-style Process Group Membership Protocol. features cluster membership, failure detection, and gossip protocol library.
Stars: ✭ 119 (-16.2%)
Mutual labels:  distributed-computing
Zunit
A powerful testing framework for ZSH projects
Stars: ✭ 140 (-1.41%)
Mutual labels:  unit-testing
Php testability
Analyses and reports testability issues of a php codebase
Stars: ✭ 136 (-4.23%)
Mutual labels:  unit-testing
Dbcleaner
Clean database for testing, inspired by database_cleaner for Ruby
Stars: ✭ 125 (-11.97%)
Mutual labels:  unit-testing

LocalCluster

Build Status Hex.pm Version Documentation

This library is designed to assist in testing distributed states in Elixir which require a number of local nodes.

The aim is to provide a small set of functions which hide the complexity of spawning local nodes, as well as providing the ease of cleaning up the started nodes. The entire library is simple shimming around the Erlang APIs for dealing with distributed nodes, As some of it is non-obvious, and as I need this code for several projects, I span it out as a smaller project.

Installation

To install it for your project, you can pull it directly from Hex. Rather than use the version shown below, you can use the the latest version from Hex (shown at the top of this README).

def deps do
  [{:local_cluster, "~> 1.2", only: [:test]}]
end

Documentation and examples can be found on Hexdocs as they're updated automatically alongside each release. Note that you should only use the :test flag in your dependency if you're not using it for other environments.

Setup

To configure your test suites for cluster testing, you need to run through a one-time setup to change some stuff in your test_helper.exs. This is required to avoid some potential issues with your node name changing after your application tree has already stated. This also reduces some bloat due to having LocalCluster.start/0 in most test cases. The snippet below can be used as a sample helper file. Make sure to change the application name to match your application name.

# start the current node as a manager
:ok = LocalCluster.start()

# start your application tree manually
Application.ensure_all_started(:my_app)

# run all tests!
ExUnit.start()

You will also need to pass the --no-start flag to mix test. Fortunately this is easy enough, as you can add an alias in your mix.exs to do this automatically:

def project do
  [
    # ...
    aliases: [
      test: "test --no-start"
    ]
    # ...
  ]
end

This library itself uses this setup, so you can copy/paste as needed or use as an example when integrating into your own codebase. Note that you must have ensured that epmd has been started before using this lib; typically with epmd -daemon.

Usage

As mentioned above, the API is deliberately tiny to make it easier to use this library when testing. Below is an example of using this library to spawn a set of child nodes for testing:

defmodule MyTest do
  use ExUnit.Case

  test "something with a required cluster" do
    nodes = LocalCluster.start_nodes("my-cluster", 3)

    [node1, node2, node3] = nodes

    assert Node.ping(node1) == :pong
    assert Node.ping(node2) == :pong
    assert Node.ping(node3) == :pong

    :ok = LocalCluster.stop_nodes([node1])

    assert Node.ping(node1) == :pang
    assert Node.ping(node2) == :pong
    assert Node.ping(node3) == :pong

    :ok = LocalCluster.stop()

    assert Node.ping(node1) == :pang
    assert Node.ping(node2) == :pang
    assert Node.ping(node3) == :pang
  end
end

After calling start_nodes/2, you will receive a list of node names you can then use to communicate with via RPC or however you'd like. Although they're automatically cleaned up when the calling process dies, you can manually stop nodes as well to test disconnection.

In the case you need to control application startup manually, you can make use of the :applications option. This option determines startup order of your applications, and allows you to exclude applications from the startup sequence. If this is not provided, the default behaviour will be to start the same applications as are running on the local node. These applications are loaded with all dependencies via Application.ensure_all_started/2.

LocalCluster.start_nodes(:spawn, 3, [
  applications: [
    :start_this_application,
    :and_then_this_one
  ]
])

If you need to load any additional files onto the remote nodes, you can make use of the :files option at startup time by providing an absolute file path to compile on the cluster. This is necessary if you wish to spawn tasks onto the cluster from inside your test code, as your test code is not loaded into the cluster automatically:

defmodule MyTest do
  use ExUnit.Case

  test "spawning tasks on a cluster" do
    nodes = LocalCluster.start_nodes(:spawn, 3, [
      files: [
        __ENV__.file
      ]
    ])

    [node1, node2, node3] = nodes

    assert Node.ping(node1) == :pong
    assert Node.ping(node2) == :pong
    assert Node.ping(node3) == :pong

    caller = self()

    Node.spawn(node1, fn ->
      send(caller, :from_node_1)
    end)

    Node.spawn(node2, fn ->
      send(caller, :from_node_2)
    end)

    Node.spawn(node3, fn ->
      send(caller, :from_node_3)
    end)

    assert_receive :from_node_1
    assert_receive :from_node_2
    assert_receive :from_node_3
  end
end

If you need to override the application environment inherrited by the remote nodes, you can use the :environment option at startup. This koption set is merged over the environment inside the started nodes:

LocalCluster.start_nodes(:spawn, 1, [
  environment: [
    my_app: [
      port: 9999
    ]
  ]
])
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].