|
1 # |
|
2 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 # All rights reserved. |
|
4 # This component and the accompanying materials are made available |
|
5 # under the terms of the License "Eclipse Public License v1.0" |
|
6 # which accompanies this distribution, and is available |
|
7 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 # |
|
9 # Initial Contributors: |
|
10 # Nokia Corporation - initial contribution. |
|
11 # |
|
12 # Contributors: |
|
13 # |
|
14 # Description: |
|
15 # Test generic classes available for use in plugin log filters |
|
16 # |
|
17 |
|
18 |
|
19 import unittest |
|
20 import filter_utils |
|
21 |
|
22 |
|
23 testRecipeTemplate = \ |
|
24 """<recipe name='%s' target='recipe_target' host="recipe_host" layer='recipe_layer' component='recipe_component' bldinf='recipe_bldinf' mmp='recipe_mmp' config='recipe_config' platform='recipe_platform' phase='recipe_phase' source='recipe_source'>" |
|
25 <![CDATA[ |
|
26 %s |
|
27 ]]><time start='0123456789.123456789' elapsed='99.999' /> |
|
28 <status exit='%s' %s attempt='%d' /> |
|
29 </recipe>""" |
|
30 |
|
31 testRecipeCalls = \ |
|
32 """+ call_to_some_tool -a arg1 -a arg2 -a arg3 |
|
33 + call_to_some_other_tool -a arg1 -a arg2 -a arg3""" |
|
34 testRecipeOutput = \ |
|
35 """output from some tool or other |
|
36 some more output from some tool or other""" |
|
37 |
|
38 # Fall-back warning and error examples |
|
39 genericWarnings = \ |
|
40 """Warning: generic warning from some tool or other |
|
41 Warning: another generic warning from some tool or other""" |
|
42 genericErrors = \ |
|
43 """Error: generic error from some tool or other |
|
44 Error: another generic error from some tool or other""" |
|
45 |
|
46 # Real world examples of mwccsym2, mwldsym2 and mwwinrc errors and warnings |
|
47 mwWarnings = \ |
|
48 """mwldsym2.exe: warning: Multiply defined symbol: ___get_MSL_init_count in |
|
49 ..\sf\os\cellularsrv\telephonyserver\etelserverandcore\SETEL\ET_PHONE.CPP:36: warning: cannot find matching deallocation function for 'CReqEntry'""" |
|
50 mwErrors = \ |
|
51 """HelloWorld.cpp:21: undefined identifier 'stuff' |
|
52 mwldsym2.exe: Specified file 'HelloWorld.o' not found""" |
|
53 mwBenign = \ |
|
54 """..\sf\os\lbs\locationrequestmgmt\locationserver\src\locserver.cpp:223: note: NOTE: CLocServer::DoNewSessionL. aMessage and aVersion not used. TBD""" |
|
55 |
|
56 |
|
57 class TestFilterUtils(unittest.TestCase): |
|
58 |
|
59 def setUp(self): |
|
60 self.__recipeFactory = filter_utils.RecipeFactory() |
|
61 |
|
62 def __createRecipeLines(self, aName, aExit, aAttempt, aCode=None, aExtras=""): |
|
63 """Customise the recipe test template for differing recipe tests |
|
64 The 'code' attribute of 'status' is optional, and different errors/warnings |
|
65 etc. can be added via aExtras""" |
|
66 code = "" |
|
67 if aCode: |
|
68 code = "code='%d'" % aCode |
|
69 midSection = testRecipeCalls + "\n" + testRecipeOutput |
|
70 if aExtras: |
|
71 midSection += "\n" + aExtras |
|
72 recipe = testRecipeTemplate % (aName, midSection, aExit, code, aAttempt) |
|
73 return recipe.split("\n") |
|
74 |
|
75 def __checkListContent(self, aExpected, aActual, aPrefixIgnore=""): |
|
76 """Compare the content of two lists of strings. |
|
77 Optionally trim a prefix from the expected results.""" |
|
78 for expected in aExpected: |
|
79 self.assertTrue(expected.lstrip(aPrefixIgnore) in aActual) |
|
80 self.assertEqual(len(aActual), len(aExpected)) |
|
81 |
|
82 def testRecipeFactory(self): |
|
83 recipeLines = self.__createRecipeLines("generic", "ok", 1) |
|
84 recipe = self.__recipeFactory.newRecipe(recipeLines[0]) |
|
85 self.assertTrue(isinstance(recipe, filter_utils.Recipe)) |
|
86 |
|
87 recipeLines = self.__createRecipeLines("win32something", "ok", 1) |
|
88 recipe = self.__recipeFactory.newRecipe(recipeLines[0]) |
|
89 self.assertTrue(isinstance(recipe, filter_utils.Win32Recipe)) |
|
90 |
|
91 def testGenericRecipe(self): |
|
92 |
|
93 # 1. Basic successful recipe |
|
94 recipeLines = self.__createRecipeLines("recipe_name", "ok", 1) |
|
95 recipe = self.__recipeFactory.newRecipe(recipeLines[0]) |
|
96 |
|
97 self.assertEqual(recipe.getDetail(filter_utils.Recipe.name), 'recipe_name') |
|
98 self.assertEqual(recipe.getDetail(filter_utils.Recipe.target), 'recipe_target') |
|
99 self.assertEqual(recipe.getDetail(filter_utils.Recipe.layer), 'recipe_layer') |
|
100 self.assertEqual(recipe.getDetail(filter_utils.Recipe.component), 'recipe_component') |
|
101 self.assertEqual(recipe.getDetail(filter_utils.Recipe.bldinf), 'recipe_bldinf') |
|
102 self.assertEqual(recipe.getDetail(filter_utils.Recipe.mmp), 'recipe_mmp') |
|
103 self.assertEqual(recipe.getDetail(filter_utils.Recipe.config), 'recipe_config') |
|
104 self.assertEqual(recipe.getDetail(filter_utils.Recipe.platform), 'recipe_platform') |
|
105 self.assertEqual(recipe.getDetail(filter_utils.Recipe.phase), 'recipe_phase') |
|
106 self.assertEqual(recipe.getDetail(filter_utils.Recipe.source), 'recipe_source') |
|
107 |
|
108 self.assertFalse(recipe.isComplete()) |
|
109 |
|
110 for x in range(1, len(recipeLines)): |
|
111 recipe.addLine(recipeLines[x]) |
|
112 |
|
113 self.assertTrue(recipe.isComplete()) |
|
114 self.assertTrue(recipe.isSuccess()) |
|
115 |
|
116 self.assertEqual(recipe.getDetail(filter_utils.Recipe.start), "0123456789.123456789") |
|
117 self.assertEqual(recipe.getDetail(filter_utils.Recipe.elapsed), 99.999) |
|
118 self.assertEqual(recipe.getDetail(filter_utils.Recipe.exit), 'ok') |
|
119 self.assertEqual(recipe.getDetail(filter_utils.Recipe.attempts), 1) |
|
120 |
|
121 # Ignore "+ " tool call prefixes that are trimmed in getCalls output |
|
122 self.__checkListContent(testRecipeCalls.split("\n"), recipe.getCalls(), "+ ") |
|
123 self.__checkListContent(testRecipeOutput.split("\n"), recipe.getOutput()) |
|
124 |
|
125 # 2. Recipe failure with errors |
|
126 recipeLines = self.__createRecipeLines("recipe_name", "failed", 3, 10, genericErrors) |
|
127 recipe = self.__recipeFactory.newRecipe() |
|
128 for line in recipeLines: |
|
129 recipe.addLine(line) |
|
130 self.assertFalse(recipe.isSuccess()) |
|
131 self.assertEqual(recipe.getDetail(filter_utils.Recipe.attempts), 3) |
|
132 self.assertEqual(recipe.getDetail(filter_utils.Recipe.code), 10) |
|
133 self.__checkListContent(genericErrors.split("\n"), recipe.getErrors()) |
|
134 |
|
135 # 3. Recipe retry with warnings |
|
136 recipeLines = self.__createRecipeLines("recipe_name", "retry", 2, 5, genericWarnings) |
|
137 recipe = self.__recipeFactory.newRecipe() |
|
138 for line in recipeLines: |
|
139 recipe.addLine(line) |
|
140 self.assertFalse(recipe.isSuccess()) |
|
141 self.assertEqual(recipe.getDetail(filter_utils.Recipe.attempts), 2) |
|
142 self.assertEqual(recipe.getDetail(filter_utils.Recipe.code), 5) |
|
143 self.__checkListContent(genericWarnings.split("\n"), recipe.getWarnings()) |
|
144 |
|
145 def testWin32Recipe(self): |
|
146 # Recipe failure with errors and warnings |
|
147 recipeLines = self.__createRecipeLines("win32something", "failed", 3, 10, mwWarnings + "\n" + mwErrors + "\n" + mwBenign) |
|
148 recipe = self.__recipeFactory.newRecipe(recipeLines[0]) |
|
149 for line in recipeLines: |
|
150 recipe.addLine(line) |
|
151 self.assertFalse(recipe.isSuccess()) |
|
152 self.assertEqual(recipe.getDetail(filter_utils.Recipe.attempts), 3) |
|
153 self.assertEqual(recipe.getDetail(filter_utils.Recipe.code), 10) |
|
154 |
|
155 self.__checkListContent(mwWarnings.split("\n"), recipe.getWarnings()) |
|
156 self.__checkListContent(mwErrors.split("\n"), recipe.getErrors()) |
|
157 |
|
158 # run all the tests |
|
159 |
|
160 from raptor_tests import SmokeTest |
|
161 |
|
162 def run(): |
|
163 t = SmokeTest() |
|
164 t.id = "999" |
|
165 t.name = "filter_utils_unit" |
|
166 |
|
167 tests = unittest.makeSuite(TestFilterUtils) |
|
168 result = unittest.TextTestRunner(verbosity=2).run(tests) |
|
169 |
|
170 if result.wasSuccessful(): |
|
171 t.result = SmokeTest.PASS |
|
172 else: |
|
173 t.result = SmokeTest.FAIL |
|
174 |
|
175 return t |