1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18/**
19 * @author Vladimir N. Molotkov
20 */
21
22package org.apache.harmony.security.tests.asn1.der;
23
24import java.io.ByteArrayInputStream;
25import java.io.IOException;
26import java.text.ParseException;
27import java.text.SimpleDateFormat;
28import java.util.Date;
29import java.util.TimeZone;
30
31import org.apache.harmony.security.asn1.ASN1UTCTime;
32import org.apache.harmony.security.asn1.DerInputStream;
33import org.apache.harmony.security.asn1.DerOutputStream;
34
35import junit.framework.TestCase;
36
37
38/**
39 * ASN.1 DER test for UTCTime type
40 *
41 * @see http://asn1.elibel.tm.fr/en/standards/index.htm
42 */
43public class DerUTCTimeEDTest extends TestCase {
44
45    private ASN1UTCTime uTime = ASN1UTCTime.getInstance();
46
47    private final int workersNumber = 10;
48    private boolean mtTestPassed;
49
50    /**
51     * UTC TIME DER Encoder test
52     *
53     * @throws ParseException
54     */
55    public final void testUTCEncoder() throws Exception {
56        // no fractional seconds (last 3 0s and "." must be trimmed out)
57        Date myDate = getGmtDate(1101980374187L);
58        byte[] encoded =
59                new DerOutputStream(uTime, myDate).encoded;
60        String rep = new String(encoded, 2, encoded[1] & 0xff, "UTF-8");
61        assertEquals("no fraction", "041202093934Z", rep);
62
63        // midnight
64        SimpleDateFormat sdf =
65                new SimpleDateFormat("dd.MM.yyyy HH:mm");
66        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
67        myDate = sdf.parse("06.06.2004 00:00");
68        encoded =
69                new DerOutputStream(uTime, myDate).encoded;
70        rep = new String(encoded, 2, encoded[1] & 0xff, "UTF-8");
71        assertEquals("midnight", "040606000000Z", rep);
72    }
73
74    /**
75     * UTC TIME DER Encoder/Decoder test
76     * (byte array case)
77     *
78     * @throws ParseException
79     * @throws IOException
80     */
81    public final void testUTCEncoderDecoder01()
82            throws ParseException,
83            IOException {
84        runTest(false);
85    }
86
87    /**
88     * UTC TIME DER Encoder/Decoder test
89     * (InputStream case)
90     *
91     * @throws ParseException
92     * @throws IOException
93     */
94    public final void testUTCEncoderDecoder02()
95            throws ParseException,
96            IOException {
97        runTest(true);
98    }
99
100    private final void runTest(boolean useInputStream)
101            throws IOException, ParseException {
102        Date myDate = new Date(1101980374187L);
103        byte[] encoded =
104                new DerOutputStream(uTime, myDate).encoded;
105        DerInputStream dis = useInputStream
106                ? new DerInputStream(new ByteArrayInputStream(encoded))
107                : new DerInputStream(encoded);
108        // the difference only fractional-seconds
109        assertEquals(187, (myDate.getTime() - ((Date) uTime.decode(dis)).getTime()));
110
111        // midnight
112        myDate = new SimpleDateFormat("MM.dd.yyyy HH:mm").
113                parse("06.06.2004 00:00");
114        encoded =
115                new DerOutputStream(uTime, myDate).encoded;
116        dis = useInputStream
117                ? new DerInputStream(new ByteArrayInputStream(encoded))
118                : new DerInputStream(encoded);
119        assertEquals(myDate, uTime.decode(dis));
120    }
121
122    public final void testMt() throws InterruptedException {
123        mtTestPassed = true;
124        Thread[] workers = new Thread[workersNumber];
125        for (int i = 0; i < workersNumber; i++) {
126            workers[i] = new TestWorker();
127        }
128        for (int i = 0; i < workersNumber; i++) {
129            workers[i].start();
130        }
131        for (int i = 0; i < workersNumber; i++) {
132            workers[i].join();
133        }
134        assertTrue(mtTestPassed);
135    }
136
137    private static Date getGmtDate(long mills) {
138        return new Date(mills);
139    }
140
141    /**
142     * MT Test worker thread
143     *
144     * @author Vladimir Molotkov
145     * @version 0.1
146     */
147    private class TestWorker extends Thread {
148
149        public void run() {
150            for (int i = 0; i < 100; i++) {
151                try {
152                    // Perform DER encoding/decoding:
153                    if (i % 2 == 0) {
154                        testUTCEncoderDecoder01();
155                    } else {
156                        testUTCEncoderDecoder02();
157                    }
158                } catch (Throwable e) {
159                    System.err.println(e);
160                    mtTestPassed = false;
161                    return;
162                }
163            }
164        }
165    }
166}
167