source: other-projects/trunk/gs3-release-maker/apache-ant-1.6.5/src/testcases/org/apache/tools/ant/taskdefs/ExecuteOnTest.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 23.2 KB
Line 
1/*
2 * Copyright 2004-2005 The Apache Software Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18package org.apache.tools.ant.taskdefs;
19
20import org.apache.tools.ant.BuildFileTest;
21import org.apache.tools.ant.util.FileUtils;
22
23import java.io.File;
24import java.io.FileReader;
25import java.io.IOException;
26import java.io.OutputStream;
27
28/**
29 * Unit test for the <apply> task.
30 */
31public class ExecuteOnTest extends BuildFileTest {
32 private static final String BUILD_PATH = "src/etc/testcases/taskdefs/exec/";
33 private static final String BUILD_FILE = BUILD_PATH + "apply.xml";
34
35 public ExecuteOnTest(String name) {
36 super(name);
37 }
38
39 public void setUp() {
40 configureProject(BUILD_FILE);
41 }
42
43 public void tearDown() {
44 executeTarget("cleanup");
45 }
46
47 public void testNoRedirect() {
48 executeTarget("no-redirect");
49 if (getProject().getProperty("test.can.run") == null) {
50 return;
51 }
52
53 String log = getLog();
54 File x = getProject().resolveFile("x");
55 File y = getProject().resolveFile("y");
56 File z = getProject().resolveFile("z");
57 int xout = log.indexOf(x + " out");
58 int yout = log.indexOf(y + " out");
59 int zout = log.indexOf(z + " out");
60 int xerr = log.indexOf(x + " err");
61 int yerr = log.indexOf(y + " err");
62 int zerr = log.indexOf(z + " err");
63 assertFalse("xout=" + xout, xout < 0);
64 assertFalse("yout=" + yout, yout < 0);
65 assertFalse("zout=" + zout, zout < 0);
66 assertFalse("xerr=" + xerr, xerr < 0);
67 assertFalse("yerr=" + yerr, yerr < 0);
68 assertFalse("zerr=" + zerr, zerr < 0);
69 assertFalse("yout < xout", yout < xout);
70 assertFalse("zout < yout", zout < yout);
71 assertFalse("yerr < xerr", yerr < xerr);
72 assertFalse("zerr < yerr", zerr < yerr);
73 }
74
75 public void testRedirect1() throws IOException {
76 executeTarget("redirect1");
77 if (getProject().getProperty("test.can.run") == null) {
78 return;
79 }
80 String actualOut = getFileString("redirect.out");
81
82 File x = getProject().resolveFile("x");
83 File y = getProject().resolveFile("y");
84 File z = getProject().resolveFile("z");
85 int xout = actualOut.indexOf(x + " out");
86 int yout = actualOut.indexOf(y + " out");
87 int zout = actualOut.indexOf(z + " out");
88 int xerr = actualOut.indexOf(x + " err");
89 int yerr = actualOut.indexOf(y + " err");
90 int zerr = actualOut.indexOf(z + " err");
91 assertFalse("xout=" + xout, xout < 0);
92 assertFalse("yout=" + yout, yout < 0);
93 assertFalse("zout=" + zout, zout < 0);
94 assertFalse("xerr=" + xerr, xerr < 0);
95 assertFalse("yerr=" + yerr, yerr < 0);
96 assertFalse("zerr=" + zerr, zerr < 0);
97 assertFalse("yout < xout", yout < xout);
98 assertFalse("zout < yout", zout < yout);
99 assertFalse("yerr < xerr", yerr < xerr);
100 assertFalse("zerr < yerr", zerr < yerr);
101 }
102
103 public void testRedirect2() throws IOException {
104 executeTarget("redirect2");
105 if (getProject().getProperty("test.can.run") == null) {
106 return;
107 }
108 String actualOut = getFileString("redirect.out");
109 String actualErr = getFileString("redirect.err");
110
111 File x = getProject().resolveFile("x");
112 File y = getProject().resolveFile("y");
113 File z = getProject().resolveFile("z");
114 int xout = actualOut.indexOf(x + " out");
115 int yout = actualOut.indexOf(y + " out");
116 int zout = actualOut.indexOf(z + " out");
117 int xerr = actualErr.indexOf(x + " err");
118 int yerr = actualErr.indexOf(y + " err");
119 int zerr = actualErr.indexOf(z + " err");
120 assertFalse("xout=" + xout, xout < 0);
121 assertFalse("yout=" + yout, yout < 0);
122 assertFalse("zout=" + zout, zout < 0);
123 assertFalse("xerr=" + xerr, xerr < 0);
124 assertFalse("yerr=" + yerr, yerr < 0);
125 assertFalse("zerr=" + zerr, zerr < 0);
126 assertFalse("yout < xout", yout < xout);
127 assertFalse("zout < yout", zout < yout);
128 assertFalse("yerr < xerr", yerr < xerr);
129 assertFalse("zerr < yerr", zerr < yerr);
130 }
131
132 public void testRedirect3() throws IOException {
133 executeTarget("redirect3");
134 if (getProject().getProperty("test.can.run") == null) {
135 return;
136 }
137 String actualOut = getFileString("redirect.out");
138
139 File x = getProject().resolveFile("x");
140 File y = getProject().resolveFile("y");
141 File z = getProject().resolveFile("z");
142 int xout = actualOut.indexOf(x + " out");
143 int yout = actualOut.indexOf(y + " out");
144 int zout = actualOut.indexOf(z + " out");
145 int xerr = getLog().indexOf(x + " err");
146 int yerr = getLog().indexOf(y + " err");
147 int zerr = getLog().indexOf(z + " err");
148 assertFalse("xout=" + xout, xout < 0);
149 assertFalse("yout=" + yout, yout < 0);
150 assertFalse("zout=" + zout, zout < 0);
151 assertFalse("xerr=" + xerr, xerr < 0);
152 assertFalse("yerr=" + yerr, yerr < 0);
153 assertFalse("zerr=" + zerr, zerr < 0);
154 assertFalse("yout < xout", yout < xout);
155 assertFalse("zout < yout", zout < yout);
156 assertFalse("yerr < xerr", yerr < xerr);
157 assertFalse("zerr < yerr", zerr < yerr);
158
159 String outProperty = getProject().getProperty("redirect.out");
160 int pxout = outProperty.indexOf(x + " out");
161 int pyout = outProperty.indexOf(y + " out");
162 int pzout = outProperty.indexOf(z + " out");
163 assertFalse("pxout=" + pxout, pxout < 0);
164 assertFalse("pyout=" + pyout, pyout < 0);
165 assertFalse("pzout=" + pzout, pzout < 0);
166 assertFalse("pyout < pxout", pyout < pxout);
167 assertFalse("pzout < pyout", pzout < pyout);
168 }
169
170 public void testRedirect4() throws IOException {
171 executeTarget("redirect4");
172 if (getProject().getProperty("test.can.run") == null) {
173 return;
174 }
175 String actualOut = getFileString("redirect.out");
176 String actualErr = getFileString("redirect.err");
177
178 File x = getProject().resolveFile("x");
179 File y = getProject().resolveFile("y");
180 File z = getProject().resolveFile("z");
181 int xout = actualOut.indexOf(x + " out");
182 int yout = actualOut.indexOf(y + " out");
183 int zout = actualOut.indexOf(z + " out");
184 int xerr = actualErr.indexOf(x + " err");
185 int yerr = actualErr.indexOf(y + " err");
186 int zerr = actualErr.indexOf(z + " err");
187 assertFalse("xout=" + xout, xout < 0);
188 assertFalse("yout=" + yout, yout < 0);
189 assertFalse("zout=" + zout, zout < 0);
190 assertFalse("xerr=" + xerr, xerr < 0);
191 assertFalse("yerr=" + yerr, yerr < 0);
192 assertFalse("zerr=" + zerr, zerr < 0);
193 assertFalse("yout < xout", yout < xout);
194 assertFalse("zout < yout", zout < yout);
195 assertFalse("yerr < xerr", yerr < xerr);
196 assertFalse("zerr < yerr", zerr < yerr);
197
198 String outProperty = getProject().getProperty("redirect.out");
199 int pxout = outProperty.indexOf(x + " out");
200 int pyout = outProperty.indexOf(y + " out");
201 int pzout = outProperty.indexOf(z + " out");
202 assertFalse("pxout=" + pxout, pxout < 0);
203 assertFalse("pyout=" + pyout, pyout < 0);
204 assertFalse("pzout=" + pzout, pzout < 0);
205 assertFalse("pyout < pxout", pyout < pxout);
206 assertFalse("pzout < pyout", pzout < pyout);
207
208 String errorProperty = getProject().getProperty("redirect.err");
209 int pxerr = errorProperty.indexOf(x + " err");
210 int pyerr = errorProperty.indexOf(y + " err");
211 int pzerr = errorProperty.indexOf(z + " err");
212 assertFalse("pxerr=" + pxerr, pxerr < 0);
213 assertFalse("pyerr=" + pyerr, pyerr < 0);
214 assertFalse("pzerr=" + pzerr, pzerr < 0);
215 assertFalse("pyerr < pxerr", pyerr < pxerr);
216 assertFalse("pzerr < pyerr", pzerr < pyerr);
217 }
218
219 public void testRedirect5() throws IOException {
220 testRedirect5or6("redirect5");
221 }
222
223 public void testRedirect6() throws IOException {
224 testRedirect5or6("redirect6");
225 }
226
227 private void testRedirect5or6(String target) throws IOException {
228 executeTarget(target);
229 if (getProject().getProperty("sed.can.run") == null) {
230 return;
231 }
232
233 assertPropertyEquals("redirect.out", getProject().replaceProperties(
234 "blah y z${line.separator}x blah z${line.separator}x y blah"));
235 assertPropertyEquals("redirect.err", "");
236 assertEquals("unexpected output",
237 "blah y z\nx blah z\nx y blah\n", getFileString("redirect.out"));
238 assertNull("unexpected error output", getFileString("redirect.err"));
239 }
240
241 public void testRedirect7() throws IOException {
242 executeTarget("redirect7");
243 if (getProject().getProperty("sed.can.run") == null) {
244 return;
245 }
246
247 assertPropertyEquals("redirect.out", "blah y z");
248 assertPropertyUnset("redirect.err");
249 assertEquals("unexpected output",
250 "x y blah\n", getFileString("redirect.out"));
251 assertNull("unexpected error output", getFileString("redirect.err"));
252 }
253
254 public void testRedirector1() {
255 executeTarget("init");
256 if (getProject().getProperty("test.can.run") == null) {
257 return;
258 }
259 expectBuildException("redirector1", "cannot have > 1 nested <redirector>s");
260 }
261
262 public void testRedirector2() throws IOException {
263 executeTarget("redirector2");
264 if (getProject().getProperty("test.can.run") == null) {
265 return;
266 }
267
268 String actualOut = getFileString("redirector.out");
269
270 File x = getProject().resolveFile("x");
271 File y = getProject().resolveFile("y");
272 File z = getProject().resolveFile("z");
273 int xout = actualOut.indexOf(x + " out");
274 int yout = actualOut.indexOf(y + " out");
275 int zout = actualOut.indexOf(z + " out");
276 int xerr = actualOut.indexOf(x + " err");
277 int yerr = actualOut.indexOf(y + " err");
278 int zerr = actualOut.indexOf(z + " err");
279 assertFalse("xout=" + xout, xout < 0);
280 assertFalse("yout=" + yout, yout < 0);
281 assertFalse("zout=" + zout, zout < 0);
282 assertFalse("xerr=" + xerr, xerr < 0);
283 assertFalse("yerr=" + yerr, yerr < 0);
284 assertFalse("zerr=" + zerr, zerr < 0);
285 assertFalse("yout < xout", yout < xout);
286 assertFalse("zout < yout", zout < yout);
287 assertFalse("yerr < xerr", yerr < xerr);
288 assertFalse("zerr < yerr", zerr < yerr);
289 }
290
291 public void testRedirector3() throws IOException {
292 executeTarget("redirector3");
293 if (getProject().getProperty("test.can.run") == null) {
294 return;
295 }
296
297 String actualOut = getFileString("redirector.out");
298 String actualErr = getFileString("redirector.err");
299
300 File x = getProject().resolveFile("x");
301 File y = getProject().resolveFile("y");
302 File z = getProject().resolveFile("z");
303 int xout = actualOut.indexOf(x + " out");
304 int yout = actualOut.indexOf(y + " out");
305 int zout = actualOut.indexOf(z + " out");
306 int xerr = actualErr.indexOf(x + " err");
307 int yerr = actualErr.indexOf(y + " err");
308 int zerr = actualErr.indexOf(z + " err");
309 assertFalse("xout=" + xout, xout < 0);
310 assertFalse("yout=" + yout, yout < 0);
311 assertFalse("zout=" + zout, zout < 0);
312 assertFalse("xerr=" + xerr, xerr < 0);
313 assertFalse("yerr=" + yerr, yerr < 0);
314 assertFalse("zerr=" + zerr, zerr < 0);
315 assertFalse("yout < xout", yout < xout);
316 assertFalse("zout < yout", zout < yout);
317 assertFalse("yerr < xerr", yerr < xerr);
318 assertFalse("zerr < yerr", zerr < yerr);
319 }
320
321 public void testRedirector4() throws IOException {
322 executeTarget("redirector4");
323 if (getProject().getProperty("test.can.run") == null) {
324 return;
325 }
326 String actualOut = getFileString("redirector.out");
327
328 File x = getProject().resolveFile("x");
329 File y = getProject().resolveFile("y");
330 File z = getProject().resolveFile("z");
331 int xout = actualOut.indexOf(x + " out");
332 int yout = actualOut.indexOf(y + " out");
333 int zout = actualOut.indexOf(z + " out");
334 int xerr = getLog().indexOf(x + " err");
335 int yerr = getLog().indexOf(y + " err");
336 int zerr = getLog().indexOf(z + " err");
337 assertFalse("xout=" + xout, xout < 0);
338 assertFalse("yout=" + yout, yout < 0);
339 assertFalse("zout=" + zout, zout < 0);
340 assertFalse("xerr=" + xerr, xerr < 0);
341 assertFalse("yerr=" + yerr, yerr < 0);
342 assertFalse("zerr=" + zerr, zerr < 0);
343 assertFalse("yout < xout", yout < xout);
344 assertFalse("zout < yout", zout < yout);
345 assertFalse("yerr < xerr", yerr < xerr);
346 assertFalse("zerr < yerr", zerr < yerr);
347
348 String outProperty = getProject().getProperty("redirector.out");
349 int pxout = outProperty.indexOf(x + " out");
350 int pyout = outProperty.indexOf(y + " out");
351 int pzout = outProperty.indexOf(z + " out");
352 assertFalse("pxout=" + pxout, pxout < 0);
353 assertFalse("pyout=" + pyout, pyout < 0);
354 assertFalse("pzout=" + pzout, pzout < 0);
355 assertFalse("pyout < pxout", pyout < pxout);
356 assertFalse("pzout < pyout", pzout < pyout);
357 }
358
359 public void testRedirector5() throws IOException {
360 testRedirector5or6("redirector5");
361 }
362
363 public void testRedirector6() throws IOException {
364 testRedirector5or6("redirector6");
365 }
366
367 private void testRedirector5or6(String target) throws IOException {
368 executeTarget(target);
369 if (getProject().getProperty("test.can.run") == null) {
370 return;
371 }
372 String actualOut = getFileString("redirector.out");
373 String actualErr = getFileString("redirector.err");
374
375 File x = getProject().resolveFile("x");
376 File y = getProject().resolveFile("y");
377 File z = getProject().resolveFile("z");
378 int xout = actualOut.indexOf(x + " out");
379 int yout = actualOut.indexOf(y + " out");
380 int zout = actualOut.indexOf(z + " out");
381 int xerr = actualErr.indexOf(x + " err");
382 int yerr = actualErr.indexOf(y + " err");
383 int zerr = actualErr.indexOf(z + " err");
384 assertFalse("xout=" + xout, xout < 0);
385 assertFalse("yout=" + yout, yout < 0);
386 assertFalse("zout=" + zout, zout < 0);
387 assertFalse("xerr=" + xerr, xerr < 0);
388 assertFalse("yerr=" + yerr, yerr < 0);
389 assertFalse("zerr=" + zerr, zerr < 0);
390 assertFalse("yout < xout", yout < xout);
391 assertFalse("zout < yout", zout < yout);
392 assertFalse("yerr < xerr", yerr < xerr);
393 assertFalse("zerr < yerr", zerr < yerr);
394
395 String outProperty = getProject().getProperty("redirector.out");
396 int pxout = outProperty.indexOf(x + " out");
397 int pyout = outProperty.indexOf(y + " out");
398 int pzout = outProperty.indexOf(z + " out");
399 assertFalse("pxout=" + pxout, pxout < 0);
400 assertFalse("pyout=" + pyout, pyout < 0);
401 assertFalse("pzout=" + pzout, pzout < 0);
402 assertFalse("pyout < pxout", pyout < pxout);
403 assertFalse("pzout < pyout", pzout < pyout);
404
405 String errorProperty = getProject().getProperty("redirector.err");
406 int pxerr = errorProperty.indexOf(x + " err");
407 int pyerr = errorProperty.indexOf(y + " err");
408 int pzerr = errorProperty.indexOf(z + " err");
409 assertFalse("pxerr=" + pxerr, pxerr < 0);
410 assertFalse("pyerr=" + pyerr, pyerr < 0);
411 assertFalse("pzerr=" + pzerr, pzerr < 0);
412 assertFalse("pyerr < pxerr", pyerr < pxerr);
413 assertFalse("pzerr < pyerr", pzerr < pyerr);
414 }
415
416 public void testRedirector7() throws IOException {
417 executeTarget("redirector7");
418 if (getProject().getProperty("test.can.run") == null) {
419 return;
420 }
421 String actualOut = getFileString("redirector.out");
422 String actualErr = getFileString("redirector.err");
423
424 File x = getProject().resolveFile("x");
425 File y = getProject().resolveFile("y");
426 File z = getProject().resolveFile("z");
427 int xout = actualOut.indexOf(x + " out");
428 int yout = actualOut.indexOf(y + " out");
429 int zout = actualOut.indexOf(z + " out");
430 int xerr = actualErr.indexOf(x + " ERROR!!!");
431 int yerr = actualErr.indexOf(y + " ERROR!!!");
432 int zerr = actualErr.indexOf(z + " ERROR!!!");
433 assertFalse("xout=" + xout, xout < 0);
434 assertFalse("yout=" + yout, yout < 0);
435 assertFalse("zout=" + zout, zout < 0);
436 assertFalse("xerr=" + xerr, xerr < 0);
437 assertFalse("yerr=" + yerr, yerr < 0);
438 assertFalse("zerr=" + zerr, zerr < 0);
439 assertFalse("yout < xout", yout < xout);
440 assertFalse("zout < yout", zout < yout);
441 assertFalse("yerr < xerr", yerr < xerr);
442 assertFalse("zerr < yerr", zerr < yerr);
443
444 String outProperty = getProject().getProperty("redirector.out");
445 int pxout = outProperty.indexOf(x + " out");
446 int pyout = outProperty.indexOf(y + " out");
447 int pzout = outProperty.indexOf(z + " out");
448 assertFalse("pxout=" + pxout, pxout < 0);
449 assertFalse("pyout=" + pyout, pyout < 0);
450 assertFalse("pzout=" + pzout, pzout < 0);
451 assertFalse("pyout < pxout", pyout < pxout);
452 assertFalse("pzout < pyout", pzout < pyout);
453
454 String errorProperty = getProject().getProperty("redirector.err");
455 int pxerr = errorProperty.indexOf(x + " ERROR!!!");
456 int pyerr = errorProperty.indexOf(y + " ERROR!!!");
457 int pzerr = errorProperty.indexOf(z + " ERROR!!!");
458 assertFalse("pxerr=" + pxerr, pxerr < 0);
459 assertFalse("pyerr=" + pyerr, pyerr < 0);
460 assertFalse("pzerr=" + pzerr, pzerr < 0);
461 assertFalse("pyerr < pxerr", pyerr < pxerr);
462 assertFalse("pzerr < pyerr", pzerr < pyerr);
463 }
464
465 public void testRedirector8() throws IOException {
466 executeTarget("redirector8");
467 if (getProject().getProperty("sed.can.run") == null) {
468 return;
469 }
470
471 assertPropertyEquals("redirector.out", getProject().replaceProperties(
472 "blah y z${line.separator}x blah z${line.separator}x y blah"));
473 assertPropertyEquals("redirector.err", "");
474 assertEquals("unexpected output",
475 "blah y z\nx blah z\nx y blah\n", getFileString("redirector.out"));
476 assertNull("unexpected error output", getFileString("redirector.err"));
477 }
478
479 public void testRedirector9() throws IOException {
480 testRedirector9Thru12("redirector9");
481 }
482
483 public void testRedirector10() throws IOException {
484 testRedirector9Thru12("redirector10");
485 }
486
487 public void testRedirector11() throws IOException {
488 testRedirector9Thru12("redirector11");
489 }
490
491 public void testRedirector12() throws IOException {
492 testRedirector9Thru12("redirector12");
493 }
494
495 private void testRedirector9Thru12(String target) throws IOException {
496 executeTarget(target);
497 if (getProject().getProperty("sed.can.run") == null) {
498 return;
499 }
500
501 assertNull("unexpected error output", getFileString("redirector.err"));
502 assertPropertyEquals("redirector.out", getProject().replaceProperties(
503 "blah after y after z${line.separator}x after blah after z"
504 + "${line.separator}x after y after blah"));
505 assertPropertyEquals("redirector.err", "");
506 assertEquals("unexpected output",
507 "blah after y after z\nx after blah after z"
508 + "\nx after y after blah\n", getFileString("redirector.out"));
509 }
510
511 public void testRedirector13() {
512 executeTarget("redirector13");
513 if (getProject().getProperty("test.can.run") == null) {
514 return;
515 }
516 String log = getLog();
517 File x = getProject().resolveFile("x");
518 File y = getProject().resolveFile("y");
519 File z = getProject().resolveFile("z");
520 int xout = log.indexOf(x + " OUTPUT???");
521 int yout = log.indexOf(y + " OUTPUT???");
522 int zout = log.indexOf(z + " OUTPUT???");
523 int xerr = log.indexOf(x + " ERROR!!!");
524 int yerr = log.indexOf(y + " ERROR!!!");
525 int zerr = log.indexOf(z + " ERROR!!!");
526 assertFalse("xout=" + xout, xout < 0);
527 assertFalse("yout=" + yout, yout < 0);
528 assertFalse("zout=" + zout, zout < 0);
529 assertFalse("xerr=" + xerr, xerr < 0);
530 assertFalse("yerr=" + yerr, yerr < 0);
531 assertFalse("zerr=" + zerr, zerr < 0);
532 assertFalse("yout < xout", yout < xout);
533 assertFalse("zout < yout", zout < yout);
534 assertFalse("yerr < xerr", yerr < xerr);
535 assertFalse("zerr < yerr", zerr < yerr);
536 }
537
538 public void testRedirector14() throws IOException {
539 executeTarget("redirector14");
540 if (getProject().getProperty("sed.can.run") == null) {
541 return;
542 }
543
544 assertEquals("unexpected log content",
545 "z after y after blahx after y after blah", getLog());
546
547 assertEquals("unexpected redirector.out content",
548 "x after blah after z\n", getFileString("redirector.out"));
549
550 assertNull("unexpected redirector.err content", getFileString("redirector.err"));
551 }
552
553 public void testIgnoreMissing() {
554 executeTarget("ignoremissing");
555 }
556
557 public void testForce() {
558 executeTarget("force");
559 }
560
561 public void testNoDest() {
562 executeTarget("testNoDest");
563 }
564
565 //borrowed from TokenFilterTest
566 private String getFileString(String filename) throws IOException {
567 String result = null;
568 FileReader reader = null;
569 try {
570 reader = new FileReader(getProject().resolveFile(filename));
571 result = FileUtils.readFully(reader);
572 } finally {
573 if (reader != null) {
574 try {
575 reader.close();
576 } catch (Throwable ignore) {
577 }
578 }
579 }
580 return result;
581 }
582
583}
Note: See TracBrowser for help on using the repository browser.