Implement Load Balancing in Jest
This challenge focuses on simulating load balancing within a testing environment using Jest. Load balancing is crucial for distributing incoming requests across multiple servers to ensure high availability and responsiveness. In this scenario, you'll implement a system that simulates distributing test execution across a pool of "workers" (simulated Jest test runners).
Problem Description
Your task is to create a TypeScript module that simulates a load balancer for Jest tests. This module should accept a list of test files and a number of available workers. It should then distribute these test files among the workers in a round-robin fashion and report which worker is responsible for executing which tests.
Key Requirements:
- Worker Pool: The load balancer needs to manage a pool of a specified number of workers.
- Test Distribution: Test files must be distributed to workers using a round-robin algorithm.
- Reporting: The load balancer should output a clear representation of which worker is assigned which test files.
- TypeScript Implementation: The solution must be written in TypeScript.
Expected Behavior:
Given a list of test files and a number of workers, the load balancer should logically assign each test file to a worker. The assignment should cycle through the workers: worker 1 gets test file 1, worker 2 gets test file 2, ..., worker N gets test file N, worker 1 gets test file N+1, and so on.
Edge Cases to Consider:
- What happens if the number of test files is less than the number of workers?
- What happens if the number of test files is zero?
- What happens if the number of workers is zero or less (though typically workers would be at least 1)?
Examples
Example 1:
Input:
testFiles = ["test/auth.test.ts", "test/users.test.ts", "test/products.test.ts", "test/orders.test.ts"]
numWorkers = 2
Output:
{
"worker1": ["test/auth.test.ts", "test/products.test.ts"],
"worker2": ["test/users.test.ts", "test/orders.test.ts"]
}
Explanation:
Worker 1 receives the 1st and 3rd test files.
Worker 2 receives the 2nd and 4th test files.
Example 2:
Input:
testFiles = ["test/setup.ts", "test/teardown.ts"]
numWorkers = 3
Output:
{
"worker1": ["test/setup.ts"],
"worker2": ["test/teardown.ts"],
"worker3": []
}
Explanation:
Worker 1 receives the 1st test file.
Worker 2 receives the 2nd test file.
Worker 3 receives no test files as there are no more to distribute.
Example 3:
Input:
testFiles = []
numWorkers = 4
Output:
{
"worker1": [],
"worker2": [],
"worker3": [],
"worker4": []
}
Explanation:
With no test files, all workers are assigned empty arrays.
Constraints
testFiles: An array of strings, where each string represents a path to a test file.numWorkers: A positive integer representing the number of available workers.- The output should be an object where keys are worker identifiers (e.g., "worker1", "worker2") and values are arrays of test file paths assigned to that worker.
- Performance is not a primary concern for this simulation; correctness of the distribution is paramount.
Notes
- You can think of "workers" as independent processes that could run Jest tests.
- The goal is to simulate the assignment of tests, not the actual execution of Jest tests.
- Consider how you will generate the worker identifiers dynamically based on
numWorkers. - A robust solution should handle the case where
numWorkersmight be 0 or negative gracefully, perhaps by returning an empty object or throwing an error, depending on interpretation. For this challenge, assumenumWorkerswill be at least 1 iftestFilesis not empty, and handle thetestFilesempty case as shown.