]> git.somenet.org - pub/jan/dst18.git/blob - ass3-elastic/src/test/java/dst/ass3/elastic/ElasticityControllerTest.java
Normalize versions across project to 2018.1
[pub/jan/dst18.git] / ass3-elastic / src / test / java / dst / ass3 / elastic / ElasticityControllerTest.java
1 package dst.ass3.elastic;
2
3 import dst.ass3.elastic.impl.ElasticityFactory;
4 import dst.ass3.messaging.IWorkloadMonitor;
5 import dst.ass3.messaging.RequestType;
6 import org.junit.After;
7 import org.junit.Before;
8 import org.junit.Test;
9 import org.junit.runner.RunWith;
10 import org.mockito.Mock;
11 import org.mockito.junit.MockitoJUnitRunner;
12
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.stream.Collectors;
18
19 import static org.mockito.ArgumentMatchers.any;
20 import static org.mockito.Mockito.*;
21
22 @RunWith(MockitoJUnitRunner.class)
23 public class ElasticityControllerTest {
24     private static final String WORKER_IMAGE = "dst/ass3-worker";
25
26     IElasticityFactory factory;
27
28     @Mock
29     IContainerService containerService;
30     @Mock
31     IWorkloadMonitor workloadMonitor;
32
33     IElasticityController elasticityController;
34     Map<RequestType, Double> processingTimes = new HashMap<>();
35     Map<RequestType, Long> workerCount = new HashMap<>();
36     Map<RequestType, Long> requestCount = new HashMap<>();
37     List<ContainerInfo> containers = new ArrayList<>();
38
39     @Before
40     public void setUp() throws Exception {
41         factory = new ElasticityFactory();
42         elasticityController = factory.createElasticityController(containerService, workloadMonitor);
43
44         processingTimes.clear();
45         processingTimes.put(RequestType.DOCUMENT, 5000.0);
46         processingTimes.put(RequestType.VIDEO, 10000.0);
47         processingTimes.put(RequestType.QUIZ, 2000.0);
48         when(workloadMonitor.getAverageProcessingTime()).thenReturn(processingTimes);
49
50         workerCount.clear();
51         workerCount.put(RequestType.DOCUMENT, 95L);
52         workerCount.put(RequestType.VIDEO, 88L);
53         workerCount.put(RequestType.QUIZ, 61L);
54         when(workloadMonitor.getWorkerCount()).thenReturn(workerCount);
55
56         requestCount.clear();
57         requestCount.put(RequestType.DOCUMENT, 600L);
58         requestCount.put(RequestType.VIDEO, 1000L);
59         requestCount.put(RequestType.QUIZ, 1000L);
60         when(workloadMonitor.getRequestCount()).thenReturn(requestCount);
61
62         containers.clear();
63         for (int i = 0; i < 95; i++) {
64             containers.add(containerInfo("documentId" + i, WORKER_IMAGE, RequestType.DOCUMENT, true));
65         }
66         for (int i = 0; i < 88; i++) {
67             containers.add(containerInfo("video" + i, WORKER_IMAGE, RequestType.VIDEO, true));
68         }
69         for (int i = 0; i < 61; i++) {
70             containers.add(containerInfo("quiz" + i, WORKER_IMAGE, RequestType.QUIZ, true));
71         }
72         when(containerService.listContainers()).thenReturn(containers);
73     }
74
75     @After
76     public void tearDown() {
77         verify(workloadMonitor, atLeast(1)).getWorkerCount();
78         verify(workloadMonitor, atLeast(1)).getRequestCount();
79         verify(workloadMonitor, atLeast(1)).getAverageProcessingTime();
80     }
81
82     @Test
83     public void notEnoughWorkers_scaleUp() throws Exception {
84         // remove 10 document workers and 10 quiz workers
85         List<ContainerInfo> containersToRemove = containers.stream()
86                 .filter(c -> c.getContainerId().startsWith("documentId7") || c.getContainerId().startsWith("quiz1"))
87                 .collect(Collectors.toList());
88         containers.removeAll(containersToRemove);
89         workerCount.put(RequestType.DOCUMENT, 85L);
90         workerCount.put(RequestType.QUIZ, 51L);
91
92         elasticityController.adjustWorkers();
93
94         verify(containerService, never()).stopContainer((String) any(String.class));
95         verify(containerService, times(15)).startWorker(RequestType.DOCUMENT);
96         verify(containerService, times(16)).startWorker(RequestType.QUIZ);
97         verify(containerService, never()).startWorker(RequestType.VIDEO);
98         verify(containerService, never()).listContainers();
99     }
100
101     @Test
102     public void tooManyWorkers_scaleDown() throws Exception {
103         // add 20 more, some should be stopped
104         for (int i = 0; i < 20; i++) {
105             containers.add(containerInfo("quiz1" + i, WORKER_IMAGE, RequestType.QUIZ, true));
106         }
107         workerCount.put(RequestType.QUIZ, 81L);
108
109         elasticityController.adjustWorkers();
110
111         verify(containerService, times(14)).stopContainer(contains("quiz"));
112         verify(containerService, never()).stopContainer(contains("video"));
113         verify(containerService, never()).stopContainer(contains("document"));
114         verify(containerService, never()).startWorker((RequestType) any(RequestType.class));
115         verify(containerService, times(1)).listContainers();
116     }
117
118     @Test
119     public void justEnoughWorkers_doNotScale() throws Exception {
120         elasticityController.adjustWorkers();
121         verify(containerService, never()).startWorker((RequestType) any(RequestType.class));
122         verify(containerService, never()).stopContainer((String) any());
123         verify(containerService, never()).listContainers();
124     }
125
126     private ContainerInfo containerInfo(String id, String image, RequestType workerType, boolean running) {
127         ContainerInfo info = new ContainerInfo();
128         info.setContainerId(id);
129         info.setImage(image);
130         info.setWorkerType(workerType);
131         info.setRunning(running);
132         return info;
133     }
134
135 }