def test_request_hooks(): sim = SimulatorKernel(outputDirectory = None) loadBalancer = MockLoadBalancer(sim, latency = 1) autoScalerController = mock.Mock() autoScalerController.controlInterval = 1 autoScalerController.onRequest = mock.Mock(return_value=0) autoScalerController.onCompleted = mock.Mock(return_value=0) autoScalerController.onControlPeriod = mock.Mock(return_value=0) autoScalerController.onStatus = mock.Mock(return_value=0) autoScaler = AutoScaler(sim, loadBalancer, controller = autoScalerController) assert str(autoScaler) server1 = mock.Mock(name = 'server1') server2 = mock.Mock(name = 'server2') autoScaler.addBackend(server1) autoScaler.addBackend(server2) r = Request() autoScaler.request(r) sim.add(100, lambda: autoScaler.scaleUp()) sim.run(until = 1000) # TODO: Check exact call parameters assert autoScalerController.onRequest.call_count == 1, autoScalerController.onRequest.call_count assert autoScalerController.onCompleted.call_count == 1, autoScalerController.onCompleted.call_count assert autoScalerController.onStatus.call_count == 3, autoScalerController.onStatus.call_count assert autoScalerController.onControlPeriod.call_count == 1000, autoScalerController.onControlPeriod.call_count
def test_with_controller_always_yes(): completedRequests = [] controller = Mock() controller.withOptional.return_value = True, 1 sim = SimulatorKernel(outputDirectory = None) server = Server(sim, serviceTimeY = 10, serviceTimeYVariance = 0, serviceTimeN = 1, serviceTimeNVariance = 0) server.controller = controller r = Request() r.onCompleted = lambda: completedRequests.append(r) sim.add(0, lambda: server.request(r)) r2 = Request() r2.onCompleted = lambda: completedRequests.append(r2) sim.add(0, lambda: server.request(r2)) sim.run() controller.withOptional.assert_called_with() assert set(completedRequests) == set([ r, r2 ]) assert abs(server.getActiveTime() - 20.0) < eps, server.getActiveTime()
def test_closed_client_off(): sim = SimulatorKernel() server = MockServer(sim) client = ClosedLoopClient(sim, server) sim.add(10, lambda: client.deactivate()) sim.run(until=100) assert server.numSeenRequests < 20, server.numSeenRequests
def test_open_client_off(): sim = SimulatorKernel() server = MockServer(sim) clients = OpenLoopClient(sim, server) clients.setRate(10) sim.add(10, lambda: clients.setRate(0)) sim.run(until=100) assert server.numSeenRequests < 110, server.numSeenRequests
def test_remove_while_request_not_in_progress(): sim = SimulatorKernel(outputDirectory = None) server1 = MockServer(sim, latency = 0.1) server2 = MockServer(sim, latency = 0.1) lb = LoadBalancer(sim) lb.addBackend(server1) lb.addBackend(server2) onShutdownCompleted = Mock() def remove_active_server(): if server1.numSeenRequests: lb.removeBackend(server1, onShutdownCompleted) else: lb.removeBackend(server2, onShutdownCompleted) r1 = Request() r1.onCompleted = Mock() sim.add(0, lambda: lb.request(r1)) sim.add(1, lambda: remove_active_server()) sim.add(1, lambda: lb.request(Request())) sim.add(2, lambda: lb.request(Request())) sim.add(2, lambda: lb.request(Request())) sim.run() r1.onCompleted.assert_called_once_with() onShutdownCompleted.assert_called_once_with() assert server1.numSeenRequests == 1 or server2.numSeenRequests == 1 assert server1.numSeenRequests == 3 or server2.numSeenRequests == 3
def test_without_controller(): completedRequests = [] sim = SimulatorKernel(outputDirectory = None) server = Server(sim, serviceTimeY = 1, serviceTimeYVariance = 0) r = Request() r.onCompleted = lambda: completedRequests.append(r) sim.add(0, lambda: server.request(r)) r2 = Request() r2.onCompleted = lambda: completedRequests.append(r2) sim.add(0, lambda: server.request(r2)) sim.run() assert set(completedRequests) == set([ r, r2 ]) assert server.getActiveTime() == 2.0, server.getActiveTime()
def test_remove_two_servers_while_request_in_progress(): sim = SimulatorKernel(outputDirectory = None) server1 = MockServer(sim, latency = 10) server2 = MockServer(sim, latency = 10) server3 = MockServer(sim, latency = 10) lb = LoadBalancer(sim) lb.algorithm = 'SQF' lb.addBackend(server1) lb.addBackend(server2) lb.addBackend(server3) onShutdownCompleted = Mock() r1 = Request() r1.onCompleted = Mock() r2 = Request() r2.onCompleted = Mock() r3 = Request() r3.onCompleted = Mock() sim.add(0, lambda: lb.request(r1)) sim.add(0, lambda: lb.request(r2)) sim.add(0, lambda: lb.request(r3)) sim.add(1, lambda: lb.removeBackend(server1, onShutdownCompleted)) sim.add(2, lambda: lb.removeBackend(server2, onShutdownCompleted)) sim.run() r1.onCompleted.assert_called_once_with() r2.onCompleted.assert_called_once_with() r3.onCompleted.assert_called_once_with() assert onShutdownCompleted.call_count == 2 assert server1.numSeenRequests == 1 assert server2.numSeenRequests == 1 assert server3.numSeenRequests == 1
def test_invalid_action(): sim = SimulatorKernel(outputDirectory = None) loadBalancer = MockLoadBalancer(sim, latency = 1) autoScalerController = mock.Mock() autoScalerController.controlInterval = 1 autoScalerController.onRequest = mock.Mock(return_value=-2) autoScalerController.onCompleted = mock.Mock(return_value=0) autoScalerController.onControlPeriod = mock.Mock(return_value=0) autoScalerController.onStatus = mock.Mock(return_value=0) autoScaler = AutoScaler(sim, loadBalancer, controller = autoScalerController) assert str(autoScaler) server1 = mock.Mock(name = 'server1') server2 = mock.Mock(name = 'server2') autoScaler.addBackend(server1) autoScaler.addBackend(server2) r = Request() autoScaler.request(r) sim.add(100, lambda: autoScaler.scaleUp()) sim.run()
def test_random_startup_delay(average=60, variance=10, values_to_test=10): rng = random.Random() startupDelayFunc = lambda: rng.normalvariate(average, variance) # "predict" future random delays by resetting the PRNG's seed random_delays = [] rng.seed(1) for _ in range(values_to_test): random_delays.append(startupDelayFunc()) rng.seed(1) sim = SimulatorKernel(outputDirectory = None) loadBalancer = MockLoadBalancer(sim, latency = 1) autoScaler = AutoScaler(sim, loadBalancer, startupDelay = startupDelayFunc) assert str(autoScaler) for i in range(values_to_test): server = mock.Mock(name = 'server' + str(i)) autoScaler.addBackend(server) # NOTE: `lambda i=i` is required to capture the current value of `i` inside # the lambda. currentTime = 0 for i in range(values_to_test): currentTime += 1 sim.add(currentTime, lambda i=i: autoScaler.scaleTo(i+1)) currentTime += random_delays[i] sim.add(currentTime-eps, lambda i=i: assert_autoscaler_status_is(autoScaler, values_to_test-i-1, 1, i, 0)) sim.add(currentTime+eps, lambda i=i: assert_autoscaler_status_is(autoScaler, values_to_test-i-1, 0, i+1, 0)) sim.run() assert_autoscaler_status_is(autoScaler, 0, 0, values_to_test, 0)
def test_scale_up_and_down(): sim = SimulatorKernel(outputDirectory = None) loadBalancer = MockLoadBalancer(sim, latency = 1) autoScaler = AutoScaler(sim, loadBalancer, startupDelay = 60) assert str(autoScaler) server1 = mock.Mock(name = 'server1') server2 = mock.Mock(name = 'server2') autoScaler.addBackend(server1) autoScaler.addBackend(server2) sim.add(0, lambda: assert_autoscaler_status_is(autoScaler, 2, 0, 0, 0)) sim.add(10, lambda: autoScaler.scaleUp()) sim.add(10, lambda: assert_autoscaler_status_is(autoScaler, 1, 1, 0, 0)) sim.add(10+59, lambda: loadBalancer.addBackend.assert_not_called()) # startup delay sim.add(10+59, lambda: assert_autoscaler_status_is(autoScaler, 1, 1, 0, 0)) sim.add(10+60+eps, lambda: assert_autoscaler_status_is(autoScaler, 1, 0, 1, 0)) sim.add(10+60+eps, lambda: loadBalancer.addBackend.assert_called_with(server1)) sim.add(100, lambda: autoScaler.scaleUp()) sim.add(100, lambda: assert_autoscaler_status_is(autoScaler, 0, 1, 1, 0)) sim.add(100+59, lambda: assert_autoscaler_status_is(autoScaler, 0, 1, 1, 0)) sim.add(100+60+eps, lambda: assert_autoscaler_status_is(autoScaler, 0, 0, 2, 0)) sim.add(100+60+eps, lambda: loadBalancer.addBackend.assert_called_with(server2)) sim.add(200, lambda: autoScaler.scaleDown()) sim.add(200, lambda: assert_autoscaler_status_is(autoScaler, 0, 0, 1, 1)) sim.add(200+1-eps, lambda: assert_autoscaler_status_is(autoScaler, 0, 0, 1, 1)) sim.add(200+1+eps, lambda: assert_autoscaler_status_is(autoScaler, 1, 0, 1, 0)) sim.run() assert loadBalancer.lastRemovedBackend == server2
def test_scale_by(): sim = SimulatorKernel(outputDirectory = None) loadBalancer = MockLoadBalancer(sim, latency = 1) autoScaler = AutoScaler(sim, loadBalancer, startupDelay = 60) assert str(autoScaler) server1 = mock.Mock(name = 'server1') server2 = mock.Mock(name = 'server2') server3 = mock.Mock(name = 'server3') server4 = mock.Mock(name = 'server4') autoScaler.addBackend(server1) autoScaler.addBackend(server2) autoScaler.addBackend(server3) autoScaler.addBackend(server4) sim.add(0, lambda: assert_autoscaler_status_is(autoScaler, 4, 0, 0, 0)) sim.add(10, lambda: autoScaler.scaleBy(2)) sim.add(10, lambda: assert_autoscaler_status_is(autoScaler, 2, 2, 0, 0)) sim.add(10+59, lambda: loadBalancer.addBackend.assert_not_called()) # startup delay sim.add(10+59, lambda: assert_autoscaler_status_is(autoScaler, 2, 2, 0, 0)) sim.add(10+60+eps, lambda: assert_autoscaler_status_is(autoScaler, 2, 0, 2, 0)) calls1 = [mock.call(server1), mock.call(server2)] sim.add(10+60+eps, lambda: loadBalancer.addBackend.assert_has_calls(calls1)) sim.add(100, lambda: autoScaler.scaleBy(2)) sim.add(100, lambda: assert_autoscaler_status_is(autoScaler, 0, 2, 2, 0)) sim.add(100+59, lambda: assert_autoscaler_status_is(autoScaler, 0, 2, 2, 0)) sim.add(100+60+eps, lambda: assert_autoscaler_status_is(autoScaler, 0, 0, 4, 0)) calls2 = [mock.call(server3), mock.call(server4)] sim.add(100+60+eps, lambda: loadBalancer.addBackend.assert_has_calls(calls2)) sim.add(200, lambda: autoScaler.scaleBy(-3)) sim.add(200, lambda: assert_autoscaler_status_is(autoScaler, 0, 0, 1, 3)) sim.add(200+1-eps, lambda: assert_autoscaler_status_is(autoScaler, 0, 0, 1, 3)) sim.add(200+1+eps, lambda: assert_autoscaler_status_is(autoScaler, 3, 0, 1, 0)) sim.run() assert loadBalancer.lastRemovedBackend == server2