source: trunk/autoquest-plugin-uml-test/src/test/java/de/ugoe/cs/autoquest/plugin/uml/UMLUtilsTest.java @ 1929

Last change on this file since 1929 was 1929, checked in by sherbold, 9 years ago
  • refactored and commented UMLUtils
  • created UTPUtils
  • moved DOM related methods from UMLUtils to SOAPUtils
  • Property svn:mime-type set to text/plain
File size: 17.6 KB
Line 
1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.plugin.uml;
16
17import java.io.File;
18import java.io.FileInputStream;
19import java.io.FileOutputStream;
20import java.util.Collection;
21import java.util.HashSet;
22import java.util.Iterator;
23import java.util.LinkedList;
24import java.util.List;
25import java.util.Properties;
26import java.util.Random;
27import java.util.Set;
28import java.util.logging.Level;
29
30//import static org.junit.Assert.*;
31
32
33
34
35import org.eclipse.uml2.uml.Interaction;
36import org.eclipse.uml2.uml.Model;
37import org.eclipse.uml2.uml.StateMachine;
38import org.eclipse.uml2.uml.UMLPackage;
39import org.junit.After;
40import org.junit.BeforeClass;
41import org.junit.Test;
42
43import de.fraunhofer.fokus.testing.ModelUtils;
44import de.ugoe.cs.autoquest.eventcore.Event;
45import de.ugoe.cs.autoquest.plugin.http.HTTPLogParser;
46import de.ugoe.cs.autoquest.plugin.http.SOAPUtils;
47import de.ugoe.cs.autoquest.plugin.http.eventcore.SOAPEventType;
48import de.ugoe.cs.autoquest.plugin.http.eventcore.SimpleSOAPEventType;
49import de.ugoe.cs.autoquest.testgeneration.RandomWalkGenerator;
50import de.ugoe.cs.autoquest.usageprofiles.FirstOrderMarkovModel;
51import de.ugoe.cs.autoquest.usageprofiles.IStochasticProcess;
52import de.ugoe.cs.util.SerializationUtils;
53import de.ugoe.cs.util.console.TextConsole;
54
55/**
56 * <p>
57 * Tests for AutoQUESTs UMLUtils
58 * </p>
59 *
60 * @author Steffen Herbold
61 */
62public class UMLUtilsTest {
63
64    private final static String OUTPUT_DIR = "target/tmp/test-outputs/";
65
66    private final static boolean DELETE_OUTPUTS = false;
67
68    // for RLUS
69    private final static TestData deda_1 = new TestData("deda_rlus_properties.prop",
70                                                        "deda_usagejournal.log",
71                                                        "deda_rlus_usageprofile.dat",
72                                                        "deda_model.uml",
73                                                        "deda_rlus_model_testsuite.uml",
74                                                        "deda_rlus_model_scheduling.uml");
75
76    // for IXS
77    private final static TestData deda_2 = new TestData("deda_ixs_properties.prop",
78                                                        "deda_usagejournal.log",
79                                                        "deda_ixs_usageprofile.dat",
80                                                        "deda_model.uml",
81                                                        "deda_ixs_model_testsuite.uml",
82                                                        "deda_ixs_model_scheduling.uml");
83
84    private final static TestData ita_1 = new TestData("ita_properties.prop",
85                                                       "ita_usagejournal.log",
86                                                       "ita_usageprofile.dat", "ita_model.uml",
87                                                       "ita_model_testsuite.uml",
88                                                       "ita_model_scheduling.uml");
89
90    private static class TestData {
91        public final String propertiesFile;
92        public final String usageJournalFile;
93        public final String usageProfileFile;
94        public final String dslModelFile;
95        public final String testSuiteFile;
96        public final String schedulingFile;
97
98        public TestData(String propertiesFile,
99                        String usageJournalFile,
100                        String usageProfileFile,
101                        String dslModelFile,
102                        String testSuiteFile,
103                        String schedulingFile)
104        {
105            this.propertiesFile = propertiesFile;
106            this.usageJournalFile = usageJournalFile;
107            this.usageProfileFile = usageProfileFile;
108            this.dslModelFile = dslModelFile;
109            this.testSuiteFile = testSuiteFile;
110            this.schedulingFile = schedulingFile;
111
112        }
113
114        @Override
115        public String toString() {
116            StringBuilder strBld = new StringBuilder();
117            strBld.append("Properties    " + propertiesFile + "\n");
118            strBld.append("Usage Journal " + usageJournalFile + "\n");
119            strBld.append("Usage Profile " + usageProfileFile + "\n");
120            strBld.append("DSL Model     " + dslModelFile + "\n");
121            strBld.append("Test Suite    " + testSuiteFile + "\n");
122            strBld.append("Scheduling    " + schedulingFile + "\n");
123            return strBld.toString();
124        }
125    }
126
127    @BeforeClass
128    public static void setUpBeforeClass() throws Exception {
129        new TextConsole(Level.SEVERE);
130    }
131
132    @After
133    public void tearDown() throws Exception {
134        if (DELETE_OUTPUTS) {
135            deleteFiles(new File(OUTPUT_DIR));
136        }
137    }
138
139    @Test(expected = java.lang.RuntimeException.class)
140    public void testCreateUMLTransitionSequence_ITA_1() throws Exception {
141        TestData testdata = ita_1;
142
143        Properties properties = loadProperties(testdata);
144        Collection<List<Event>> sequences = loadAndPreprocessUsageJournal(testdata, properties);
145        Model model =
146            ModelUtils.loadModel(ClassLoader.getSystemResourceAsStream(testdata.dslModelFile));
147
148        StateMachine stateMachine =
149            (StateMachine) model.getPackagedElement("StateMachineTransportService", true,
150                                                    UMLPackage.Literals.STATE_MACHINE, true);
151
152        Collection<List<Event>> umlSequences = new LinkedList<>();
153
154        // remove everything but transport from sequences
155        for (List<Event> sequence : sequences) {
156            for (Iterator<Event> eventIter = sequence.iterator(); eventIter.hasNext();) {
157                Event event = eventIter.next();
158                SOAPEventType eventType = (SOAPEventType) event.getType();
159                if (!"TransportService".equals(eventType.getServiceName())) {
160                    eventIter.remove();
161                }
162            }
163            umlSequences.add(UMLUtils.createUMLTransitionSequence(sequence, stateMachine));
164        }
165    }
166
167    @Test
168    public void testConvertStateMachineToUsageProfile__ITA_1() throws Exception {
169        TestData testdata = ita_1;
170
171        Properties properties = loadProperties(testdata);
172        Collection<List<Event>> sequences = loadAndPreprocessUsageJournal(testdata, properties);
173
174        Model model =
175            ModelUtils.loadModel(ClassLoader.getSystemResourceAsStream(testdata.dslModelFile));
176
177        // remove everything but transport from sequences
178        for (List<Event> sequence : sequences) {
179            for (Iterator<Event> eventIter = sequence.iterator(); eventIter.hasNext();) {
180                Event event = eventIter.next();
181                SOAPEventType eventType = (SOAPEventType) event.getType();
182                if (!"TransportService".equals(eventType.getServiceName())) {
183                    eventIter.remove();
184                }
185            }
186        }
187
188        StateMachine stateMachine =
189            (StateMachine) model.getPackagedElement("StateMachineTransportService", true,
190                                                    UMLPackage.Literals.STATE_MACHINE, true);
191
192        UMLUtils.convertStateMachineToUsageProfile(sequences, stateMachine);
193
194        ModelUtils.writeModelToFile(model, OUTPUT_DIR + "ita_v2_result.uml");
195    }
196
197    @Test
198    public void testCreateInteractionFromEventSequence_DEDA_1() throws Exception {
199        createInteractionFromEventSequenceWorkflow(deda_1);
200    }
201
202    @Test
203    public void testCreateInteractionFromEventSequence_DEDA_2() throws Exception {
204        createInteractionFromEventSequenceWorkflow(deda_2);
205    }
206
207    @Test
208    public void testCreateInteractionFromEventSequence_ITA_1() throws Exception {
209        createInteractionFromEventSequenceWorkflow(ita_1);
210    }
211
212    @Test
213    public void testCalculateUsageScore_DEDA_1() throws Exception {
214        calculateUsageScoreWorkflow(deda_1);
215    }
216
217    @Test
218    public void testCalculateUsageScore_DEDA_2() throws Exception {
219        calculateUsageScoreWorkflow(deda_2);
220    }
221
222    @Test
223    public void testCalculateUsageScore_ITA_1() throws Exception {
224        calculateUsageScoreWorkflow(ita_1);
225    }
226
227    @Test
228    public void testCreateScheduling_DEDA_1() throws Exception {
229        createSchedulingWorkflow(deda_1);
230    }
231
232    @Test
233    public void testCreateScheduling_DEDA_2() throws Exception {
234        createSchedulingWorkflow(deda_2);
235    }
236
237    @Test
238    public void testCreateScheduling_ITA() throws Exception {
239        createSchedulingWorkflow(ita_1);
240    }
241
242    @Test
243    public void testValidateModelWithLog_DEDA_1() throws Exception {
244        validateModelWithLogWorkflow(deda_1);
245    }
246
247    @Test
248    public void testValidateModelWithLog_DEDA_2() throws Exception {
249        validateModelWithLogWorkflow(deda_2);
250    }
251
252    @Test
253    public void testValidateModelWithLog_ITA_1() throws Exception {
254        validateModelWithLogWorkflow(ita_1);
255    }
256
257    private void validateModelWithLogWorkflow(TestData testdata) throws Exception {
258        Properties properties = loadProperties(testdata);
259        Collection<List<Event>> sequences = loadAndPreprocessUsageJournal(testdata, properties);
260        Model model =
261            ModelUtils.loadModel(ClassLoader.getSystemResourceAsStream(testdata.dslModelFile));
262
263        // run validation
264        int violations =
265            UMLUtils.validateModelWithLog(sequences, model, properties.getProperty("test.context"));
266        if (violations == 0) {
267            System.out.println("No problems found.");
268        }
269        else {
270            System.out.println(violations + " violations found.");
271        }
272    }
273
274    private void createInteractionFromEventSequenceWorkflow(TestData testdata) throws Exception {
275        Properties properties = loadProperties(testdata);
276        Collection<List<Event>> sequences = loadAndPreprocessUsageJournal(testdata, properties);
277        Model model =
278            ModelUtils.loadModel(ClassLoader.getSystemResourceAsStream(testdata.dslModelFile));
279
280        // create a test case for each observed sequence
281        int i = 0;
282        for (List<Event> sequence : sequences) {
283            UMLUtils.createInteractionFromEventSequence(sequence, model,
284                                                        properties.getProperty("testcases.prefix") +
285                                                            "_" + i,
286                                                        properties.getProperty("test.context"));
287            i++;
288        }
289
290        ModelUtils.writeModelToFile(model, OUTPUT_DIR + testdata.testSuiteFile);
291    }
292
293    private void calculateUsageScoreWorkflow(TestData testdata) throws Exception {
294        Properties properties = loadProperties(testdata);
295        Collection<List<Event>> sequences = loadAndPreprocessUsageJournal(testdata, properties);
296        Model model =
297            ModelUtils.loadModel(ClassLoader.getSystemResourceAsStream(testdata.dslModelFile));
298        IStochasticProcess usageProfile = createUsageProfile(testdata, sequences);
299        Collection<List<Event>> generatedSequences =
300            createRandomSequences(usageProfile, properties);
301
302        int i = 1;
303        List<Interaction> interactions = new LinkedList<>();
304        int[] lengths = new int[generatedSequences.size()];
305        for (List<Event> sequence : generatedSequences) {
306            interactions.add(UMLUtils.createInteractionFromEventSequence(sequence, model,
307                                                        properties.getProperty("testcases.prefix") +
308                                                            "_" + i,
309                                                        properties.getProperty("test.context")));
310            lengths[i - 1] = sequence.size();
311            i++;
312        }
313        for (int j = 0; j < interactions.size(); j++) {
314            double usageScore = UMLUtils.calculateUsageScore(interactions.get(j), usageProfile);
315            System.out.format("usage score %02d: %.2f \t %d\n", j + 1, usageScore, lengths[j]);
316        }
317    }
318
319    private void createSchedulingWorkflow(TestData testdata) throws Exception {
320        Properties properties = loadProperties(testdata);
321        Collection<List<Event>> sequences = loadAndPreprocessUsageJournal(testdata, properties);
322        Model model =
323            ModelUtils.loadModel(ClassLoader.getSystemResourceAsStream(testdata.dslModelFile));
324        IStochasticProcess usageProfile = createUsageProfile(testdata, sequences);
325        Collection<List<Event>> generatedSequences =
326            createRandomSequences(usageProfile, properties);
327        int i = 1;
328        for (List<Event> sequence : generatedSequences) {
329            UMLUtils.createInteractionFromEventSequence(sequence, model,
330                                                        properties.getProperty("testcases.prefix") +
331                                                            "_" + i,
332                                                        properties.getProperty("test.context"));
333            i++;
334        }
335
336        UMLUtils.createScheduling(model, usageProfile, properties.getProperty("test.context"));
337
338        ModelUtils.writeModelToFile(model, OUTPUT_DIR + testdata.schedulingFile);
339    }
340
341    private Properties loadProperties(TestData testdata) throws Exception {
342        Properties properties = new Properties();
343        properties.load(new FileInputStream(ClassLoader.getSystemResource(testdata.propertiesFile)
344            .getFile()));
345        return properties;
346    }
347
348    private Collection<List<Event>> loadAndPreprocessUsageJournal(TestData testdata,
349                                                                  Properties properties)
350        throws Exception
351    {
352        // load usage journal
353        HTTPLogParser parser =
354            new HTTPLogParser(new File(ClassLoader.getSystemResource(testdata.propertiesFile)
355                .getFile()));
356        parser.parseFile(new File(ClassLoader.getSystemResource(testdata.usageJournalFile)
357            .getFile()));
358        Collection<List<Event>> sequences = parser.getSequences();
359
360        // remove non SOAP events and convert to SimpleSOAPEventType
361        Collection<List<Event>> simpleSOAPSequences = new LinkedList<>();
362        for (List<Event> sequence : sequences) {
363            simpleSOAPSequences.add(SOAPUtils.convertToSimpleSOAPEvent(sequence, true));
364        }
365
366        // remove calls to ingored services
367        Set<String> ignoredServices = new HashSet<>();
368        String ignoredServicesString = properties.getProperty("test.ignored.services");
369        if (ignoredServicesString != null) {
370            for (String service : ignoredServicesString.split(",")) {
371                ignoredServices.add(service.trim());
372            }
373        }
374
375        for (List<Event> sequence : simpleSOAPSequences) {
376            for (Iterator<Event> eventIter = sequence.iterator(); eventIter.hasNext();) {
377                Event event = eventIter.next();
378                SimpleSOAPEventType eventType = (SimpleSOAPEventType) event.getType();
379                if (ignoredServices.contains(eventType.getServiceName())) {
380                    eventIter.remove();
381                }
382            }
383        }
384        return simpleSOAPSequences;
385    }
386
387    private IStochasticProcess createUsageProfile(TestData testdata, Collection<List<Event>> sequences)
388        throws Exception
389    {
390        FirstOrderMarkovModel usageProfile = new FirstOrderMarkovModel(new Random(1));
391        usageProfile.train(sequences);
392        FileOutputStream fos = new FileOutputStream(OUTPUT_DIR + testdata.usageProfileFile);
393        SerializationUtils.serialize(usageProfile, fos);
394        fos.close();
395        return usageProfile;
396    }
397
398    private Collection<List<Event>> createRandomSequences(IStochasticProcess usageProfile,
399                                                          Properties properties) throws Exception
400    {
401        int numberOfTestCases = Integer.parseInt(properties.getProperty("testcases.number"));
402        int testCaseMinLength = Integer.parseInt(properties.getProperty("testcases.minlenth", "1"));
403        int testCaseMaxLength =
404            Integer.parseInt(properties.getProperty("testcases.maxlenth", "100"));
405        int maxIter = numberOfTestCases * 100;
406        RandomWalkGenerator testGenerator =
407            new RandomWalkGenerator(numberOfTestCases, testCaseMinLength, testCaseMaxLength, true,
408                                    maxIter);
409        return testGenerator.generateTestSuite(usageProfile);
410    }
411
412    private void deleteFiles(File file) {
413        if (file.exists()) {
414            if (file.isDirectory()) {
415                for (File child : file.listFiles()) {
416                    deleteFiles(child);
417                }
418            }
419
420            try {
421                file.delete();
422            }
423            catch (Exception e) {
424                // ignore and delete as much as possible
425            }
426        }
427    }
428
429}
Note: See TracBrowser for help on using the repository browser.