m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
path: root/src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/StanikTest.java
blob: 3ad176a7cd5f95856db9f87d3b50f0136caa1df7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
package pl.edu.mimuw.cloudatlas.agent.modules;

import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import pl.edu.mimuw.cloudatlas.agent.messages.AgentMessage;
import pl.edu.mimuw.cloudatlas.agent.messages.GetStateMessage;
import pl.edu.mimuw.cloudatlas.agent.messages.RemoveZMIMessage;
import pl.edu.mimuw.cloudatlas.agent.messages.ResponseMessage;
import pl.edu.mimuw.cloudatlas.agent.messages.SetAttributeMessage;
import pl.edu.mimuw.cloudatlas.agent.messages.StateMessage;
import pl.edu.mimuw.cloudatlas.agent.messages.UpdateAttributesMessage;
import pl.edu.mimuw.cloudatlas.agent.messages.UpdateQueriesMessage;
import pl.edu.mimuw.cloudatlas.agent.MockExecutor;
import pl.edu.mimuw.cloudatlas.model.Attribute;
import pl.edu.mimuw.cloudatlas.model.AttributesMap;
import pl.edu.mimuw.cloudatlas.model.PathName;
import pl.edu.mimuw.cloudatlas.model.TestUtil;
import pl.edu.mimuw.cloudatlas.model.Value;
import pl.edu.mimuw.cloudatlas.model.ValueDuration;
import pl.edu.mimuw.cloudatlas.model.ValueInt;
import pl.edu.mimuw.cloudatlas.model.ValueQuery;
import pl.edu.mimuw.cloudatlas.model.ValueString;
import pl.edu.mimuw.cloudatlas.model.ValueTime;
import pl.edu.mimuw.cloudatlas.model.ValueUtils;
import pl.edu.mimuw.cloudatlas.model.ZMI;

import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;

public class StanikTest {
    private Stanik stanik;
    private MockExecutor executor;
    private ValueTime testTime;
    private static final long freshnessPeriod = 1000;

    @Before
    public void setupLocals() {
        stanik = new Stanik(new PathName("/new"), freshnessPeriod);
        executor = new MockExecutor(stanik);
        testTime = ValueUtils.currentTime();
    }

    @Test
    public void getEmptyState() throws Exception {
        GetStateMessage message = new GetStateMessage("test_msg", 0, ModuleType.TEST, 42);
        stanik.handleTyped(message);
        assertEquals(1, executor.messagesToPass.size());
        ResponseMessage receivedMessage = (ResponseMessage) executor.messagesToPass.take();
        assertEquals(ModuleType.TEST, receivedMessage.getDestinationModule());
        assertEquals(ResponseMessage.Type.STATE, receivedMessage.getType());
        assertEquals(42, receivedMessage.getRequestId());
        StateMessage stateMessage = (StateMessage) receivedMessage;
        ZMI zmi = stateMessage.getZMI();
        assertNull(zmi.getFather());
        assertTrue(zmi.getSons().isEmpty());
        assertEquals(3, TestUtil.iterableSize(zmi.getAttributes()));
        assertEquals(new ValueInt(0l), zmi.getAttributes().getOrNull("level"));
        assertEquals(new ValueString("/new"), zmi.getAttributes().getOrNull("owner"));
       Map<Attribute, ValueQuery>  queries = stateMessage.getQueries();
        assertEquals(2, TestUtil.iterableSize(queries.keySet()));
    }

    @Test
    public void hierarchyIsDeepCopy() throws Exception {
        GetStateMessage message = new GetStateMessage("test_msg", 0, ModuleType.TEST, 42);
        stanik.handleTyped(message);
        StateMessage receivedMessage = (StateMessage) executor.messagesToPass.poll();
        assertNotNull(receivedMessage);
        AttributesMap attributes = receivedMessage.getZMI().getAttributes();
        assertNull(attributes.getOrNull("foo"));
        attributes.add("foo", new ValueInt(1337l));

        GetStateMessage newMessage = new GetStateMessage("test_msg2", 123, ModuleType.TEST, 43);
        stanik.handleTyped(newMessage);
        StateMessage newReceivedMessage = (StateMessage) executor.messagesToPass.poll();
        AttributesMap newAttributes = newReceivedMessage.getZMI().getAttributes();
        assertNull(newAttributes.getOrNull("foo"));
    }

    @Test
    public void updateRootAttributes() throws Exception {
        AttributesMap attributes = new AttributesMap();
        attributes.add("foo", new ValueInt(1337l));
        attributes.add("bar", new ValueString("baz"));
        attributes.add("timestamp", testTime);
        UpdateAttributesMessage message = new UpdateAttributesMessage("test_msg", 0, "/", attributes);
        stanik.handleTyped(message);
        AttributesMap actualAttributes = stanik.getHierarchy().getAttributes();
        assertEquals(3, TestUtil.iterableSize(actualAttributes));
        assertEquals(new ValueInt(1337l), actualAttributes.get("foo"));
        assertEquals(new ValueString("baz"), actualAttributes.get("bar"));
        assertEquals(testTime, actualAttributes.getOrNull("timestamp"));
    }

    @Test
    public void updateWithNewZone() throws Exception {
        AttributesMap attributes = new AttributesMap();
        attributes.add("foo", new ValueInt(1337l));
        attributes.add("bar", new ValueString("baz"));
        attributes.add("name", new ValueString("new"));
        attributes.add("timestamp", testTime);
        UpdateAttributesMessage message = new UpdateAttributesMessage("test_msg", 0, "/new", attributes);
        stanik.handleTyped(message);
        AttributesMap actualAttributes = stanik.getHierarchy().findDescendant("/new").getAttributes();
        assertEquals(4, TestUtil.iterableSize(actualAttributes));
        assertEquals(new ValueInt(1337l), actualAttributes.getOrNull("foo"));
        assertEquals(new ValueString("baz"), actualAttributes.getOrNull("bar"));
        assertEquals(new ValueString("new"), actualAttributes.getOrNull("name"));
        assertEquals(testTime, actualAttributes.getOrNull("timestamp"));
    }

    @Test
    public void newZoneHasNewLevel() throws Exception {
        AttributesMap attributes = new AttributesMap();
        attributes.add("foo", new ValueInt(1337l));
        attributes.add("bar", new ValueString("baz"));
        attributes.add("name", new ValueString("new"));
        attributes.add("timestamp", testTime);
        UpdateAttributesMessage message = new UpdateAttributesMessage("test_msg", 0, "/new", attributes);
        stanik.handleTyped(message);
        GetStateMessage newMessage = new GetStateMessage("test_msg2", 123, ModuleType.TEST, 43);
        stanik.handleTyped(newMessage);

        StateMessage newReceivedMessage = (StateMessage) executor.messagesToPass.poll();
        AttributesMap actualAttributes = newReceivedMessage.getZMI().findDescendant("/new").getAttributes();
        assertEquals(7, TestUtil.iterableSize(actualAttributes));
        assertEquals(new ValueInt(1337l), actualAttributes.getOrNull("foo"));
        assertEquals(new ValueString("baz"), actualAttributes.getOrNull("bar"));
        assertEquals(new ValueString("new"), actualAttributes.getOrNull("name"));
        assertEquals(new ValueString("/new"), actualAttributes.getOrNull("owner"));
        assertEquals(new ValueInt(1l), actualAttributes.getOrNull("cardinality"));
        assertEquals(testTime, actualAttributes.getOrNull("timestamp"));
        assertEquals(new ValueInt(1l), actualAttributes.getOrNull("level"));
    }

    @Test
    public void updateWithRemovedAttributes() throws Exception {
        AttributesMap attributes = new AttributesMap();
        attributes.add("foo", new ValueInt(1337l));
        attributes.add("bar", new ValueString("baz"));
        UpdateAttributesMessage message = new UpdateAttributesMessage("test_msg", 0, "/", attributes);
        attributes.add("timestamp", testTime);
        stanik.handleTyped(message);

        AttributesMap newAttributes = new AttributesMap();
        ValueTime newTime = (ValueTime) testTime.addValue(new ValueDuration(1l));
        newAttributes.add("timestamp", newTime);
        newAttributes.add("foo", new ValueInt(1338l));
        UpdateAttributesMessage newMessage = new UpdateAttributesMessage("test_msg2", 0, "/", newAttributes);
        stanik.handleTyped(newMessage);

        AttributesMap actualAttributes = stanik.getHierarchy().getAttributes();
        assertEquals(2, TestUtil.iterableSize(actualAttributes));
        assertEquals(new ValueInt(1338l), actualAttributes.getOrNull("foo"));
        assertEquals(newTime, actualAttributes.getOrNull("timestamp"));
    }

    @Test
    public void dontApplyUpdateWithOlderTimestamp() throws Exception {
        AttributesMap attributes = new AttributesMap();
        attributes.add("foo", new ValueInt(1337l));
        attributes.add("timestamp", testTime);
        UpdateAttributesMessage message = new UpdateAttributesMessage("test_msg", 0, "/", attributes);
        stanik.handleTyped(message);

        AttributesMap oldAttributes = new AttributesMap();
        oldAttributes.add("foo", new ValueInt(1336l));
        ValueTime olderTime = (ValueTime) testTime.subtract(new ValueDuration(1l));
        oldAttributes.add("timestamp", olderTime);
        UpdateAttributesMessage newMessage = new UpdateAttributesMessage("test_msg2", 0, "/", oldAttributes);
        stanik.handleTyped(newMessage);

        AttributesMap actualAttributes = stanik.getHierarchy().getAttributes();
        assertEquals(2, TestUtil.iterableSize(actualAttributes));
        assertEquals(new ValueInt(1337l), actualAttributes.getOrNull("foo"));
        assertEquals(testTime, actualAttributes.getOrNull("timestamp"));
    }

    @Test
    public void dontApplyWithStaleTimestamp() throws Exception {
        AttributesMap attributes = new AttributesMap();
        attributes.add("foo", new ValueInt(1337l));
        attributes.add("timestamp", (ValueTime) testTime.subtract(new ValueDuration(freshnessPeriod + 100)));
        attributes.add("name", new ValueString("new"));
        UpdateAttributesMessage message = new UpdateAttributesMessage("test_msg", 0, "/new", attributes);
        stanik.handleTyped(message);

        assertFalse(stanik.getHierarchy().descendantExists(new PathName("/new")));
    }

    @Test
    public void zoneRemovedAfterFreshnessPeriod() throws Exception {
        AttributesMap attributes = new AttributesMap();
        attributes.add("foo", new ValueInt(1337l));
        attributes.add("timestamp", testTime);
        attributes.add("name", new ValueString("new"));
        UpdateAttributesMessage message = new UpdateAttributesMessage("test_msg", 0, "/new", attributes);
        stanik.handleTyped(message);
        Thread.sleep(freshnessPeriod + 100);

        AttributesMap attributes2 = new AttributesMap();
        attributes2.add("timestamp", ValueUtils.currentTime());
        UpdateAttributesMessage message2 = new UpdateAttributesMessage("test_msg", 0, "/", attributes2);
        stanik.handleTyped(message2);

        GetStateMessage getStateMessage = new GetStateMessage("", 0, ModuleType.TEST, 0);
        stanik.handleTyped(getStateMessage);

        StateMessage newReceivedMessage = (StateMessage) executor.messagesToPass.poll();
        assertNotNull(newReceivedMessage);
        assertFalse(newReceivedMessage.getZMI().descendantExists(new PathName("/new")));
        assertFalse(stanik.getHierarchy().descendantExists(new PathName("/new")));
    }

    @Test
    public void addQuery() throws Exception {
        HashMap<Attribute, ValueQuery> queries = new HashMap<Attribute, ValueQuery>();
        queries.put(new Attribute("&query"), new ValueQuery("SELECT 1 AS one", 42l));
        UpdateQueriesMessage message = new UpdateQueriesMessage("test_msg", 0, queries);
        System.out.println(message);
        stanik.handleTyped(message);

        HashMap<Attribute, ValueQuery> actualQueries = stanik.getQueries();
        assertEquals(3, TestUtil.iterableSize(actualQueries.keySet()));
        assertTrue(actualQueries.containsKey(new Attribute("&query")));
        ValueQuery timestampedQuery = actualQueries.get(new Attribute("&query"));
        assertEquals(42l, timestampedQuery.getTimestamp());
        assertEquals("SELECT 1 AS one", timestampedQuery.getCode());
    }

    @Test
    public void updateQueries() throws Exception {
        HashMap<Attribute, ValueQuery> queries = new HashMap<Attribute, ValueQuery>();
        queries.put(new Attribute("&query1"), new ValueQuery("SELECT 1 AS one", 42l));
        queries.put(new Attribute("&query3"), new ValueQuery("SELECT 23 AS x", 43l));
        queries.put(new Attribute("&query4"), new ValueQuery("SELECT 1000 AS foo", 43l));
        UpdateQueriesMessage message = new UpdateQueriesMessage("test_msg", 0, queries);
        stanik.handleTyped(message);

        HashMap<Attribute, ValueQuery> otherQueries = new HashMap<Attribute, ValueQuery>();
        otherQueries.put(new Attribute("&query1"), new ValueQuery("SELECT 2 AS one", 41l));
        otherQueries.put(new Attribute("&query2"), new ValueQuery("SELECT 42 AS answer", 39l));
        otherQueries.put(new Attribute("&query3"), new ValueQuery("SELECT 17 AS y", 44l));
        UpdateQueriesMessage otherMessage = new UpdateQueriesMessage("test_msg", 0, otherQueries);
        stanik.handleTyped(otherMessage);

        HashMap<Attribute, ValueQuery> actualQueries = stanik.getQueries();
        assertEquals(6, TestUtil.iterableSize(actualQueries.keySet()));
        assertTrue(actualQueries.containsKey(new Attribute("&query1")));
        assertTrue(actualQueries.containsKey(new Attribute("&query2")));
        assertTrue(actualQueries.containsKey(new Attribute("&query3")));
        assertTrue(actualQueries.containsKey(new Attribute("&query4")));

        ValueQuery timestampedQuery1 = actualQueries.get(new Attribute("&query1"));
        assertEquals(42l, timestampedQuery1.getTimestamp());
        assertEquals("SELECT 1 AS one", timestampedQuery1.getCode());

        ValueQuery timestampedQuery2 = actualQueries.get(new Attribute("&query2"));
        assertEquals(39l, timestampedQuery2.getTimestamp());
        assertEquals("SELECT 42 AS answer", timestampedQuery2.getCode());

        ValueQuery timestampedQuery3 = actualQueries.get(new Attribute("&query3"));
        assertEquals(44l, timestampedQuery3.getTimestamp());
        assertEquals("SELECT 17 AS y", timestampedQuery3.getCode());

        ValueQuery timestampedQuery4 = actualQueries.get(new Attribute("&query4"));
        assertEquals(43l, timestampedQuery4.getTimestamp());
        assertEquals("SELECT 1000 AS foo", timestampedQuery4.getCode());
    }

    @Test
    public void removeZMI() throws Exception {
        AttributesMap attributes = new AttributesMap();
        attributes.add("foo", new ValueInt(1337l));
        attributes.add("bar", new ValueString("baz"));
        attributes.add("name", new ValueString("new"));
        attributes.add("timestamp", testTime);
        UpdateAttributesMessage message = new UpdateAttributesMessage("test_msg", 0, "/new", attributes);
        stanik.handleTyped(message);

        RemoveZMIMessage removeMessage = new RemoveZMIMessage("test_msg2", 0, "/new", (ValueTime) testTime.addValue(new ValueDuration(1l)));
        stanik.handleTyped(removeMessage);

        assertFalse(stanik.getHierarchy().descendantExists(new PathName("/new")));
    }

    @Test
    public void dontRemoveZMIIfTimestampOlder() throws Exception {
        AttributesMap attributes = new AttributesMap();
        attributes.add("foo", new ValueInt(1337l));
        attributes.add("bar", new ValueString("baz"));
        attributes.add("name", new ValueString("new"));
        attributes.add("timestamp", testTime);
        UpdateAttributesMessage message = new UpdateAttributesMessage("test_msg", 0, "/new", attributes);
        stanik.handleTyped(message);

        RemoveZMIMessage removeMessage = new RemoveZMIMessage("test_msg2", 0, "/new", (ValueTime) testTime.subtract(new ValueDuration(1l)));
        stanik.handleTyped(removeMessage);

        stanik.getHierarchy().findDescendant("/new");
    }

    @Test
    public void setOldAttribute() throws Exception {
        AttributesMap attributes = new AttributesMap();
        attributes.add("foo", new ValueInt(1337l));
        attributes.add("name", new ValueString("new"));
        attributes.add("timestamp", testTime);
        UpdateAttributesMessage message = new UpdateAttributesMessage("test_msg", 0, "/new", attributes);
        stanik.handleTyped(message);

        SetAttributeMessage setMessage = new SetAttributeMessage("test_msg2", 0, "/new", new Attribute("foo"), new ValueInt(43l), (ValueTime) testTime.subtract(new ValueDuration(1l)));
        stanik.handleTyped(setMessage);

        AttributesMap actualAttributes = stanik.getHierarchy().findDescendant("/new").getAttributes();
        assertEquals(3, TestUtil.iterableSize(actualAttributes));
        assertEquals(new ValueInt(43l), actualAttributes.getOrNull("foo"));
        assertEquals(testTime, actualAttributes.getOrNull("timestamp"));
    }

    @Test
    public void setOldAttribute2() throws Exception {
        AttributesMap attributes = new AttributesMap();
        attributes.add("foo", new ValueInt(1337l));
        attributes.add("name", new ValueString("new"));
        attributes.add("timestamp", testTime);
        UpdateAttributesMessage message = new UpdateAttributesMessage("test_msg", 0, "/new", attributes);
        stanik.handleTyped(message);

        ValueTime newTime = (ValueTime) testTime.addValue(new ValueDuration(1l));
        SetAttributeMessage setMessage = new SetAttributeMessage("test_msg2", 0, "/new", new Attribute("foo"), new ValueInt(43l), newTime);
        stanik.handleTyped(setMessage);

        AttributesMap actualAttributes = stanik.getHierarchy().findDescendant("/new").getAttributes();
        assertEquals(3, TestUtil.iterableSize(actualAttributes));
        assertEquals(new ValueInt(43l), actualAttributes.getOrNull("foo"));
        assertEquals(newTime, actualAttributes.getOrNull("timestamp"));
    }

    @Test
    public void setNewAttribute() throws Exception {
        AttributesMap attributes = new AttributesMap();
        attributes.add("foo", new ValueInt(1337l));
        attributes.add("name", new ValueString("new"));
        attributes.add("timestamp", testTime);
        UpdateAttributesMessage message = new UpdateAttributesMessage("test_msg", 0, "/new", attributes);
        stanik.handleTyped(message);

        ValueTime newTime = (ValueTime) testTime.addValue(new ValueDuration(1l));
        SetAttributeMessage setMessage = new SetAttributeMessage("test_msg2", 0, "/new", new Attribute("bar"), new ValueInt(43l), newTime);
        stanik.handleTyped(setMessage);

        AttributesMap actualAttributes = stanik.getHierarchy().findDescendant("/new").getAttributes();
        assertEquals(4, TestUtil.iterableSize(actualAttributes));
        assertEquals(new ValueInt(1337l), actualAttributes.getOrNull("foo"));
        assertEquals(new ValueInt(43l), actualAttributes.getOrNull("bar"));
        assertEquals(newTime, actualAttributes.getOrNull("timestamp"));
    }
}