2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.pap.xacml.rest.components;
24 import java.io.IOException;
25 import java.nio.file.Paths;
26 import java.util.Date;
27 import java.util.List;
29 import javax.persistence.EntityManager;
30 import javax.persistence.EntityManagerFactory;
31 import javax.persistence.Persistence;
32 import javax.persistence.PersistenceException;
33 import javax.persistence.Query;
35 import org.apache.commons.io.FileUtils;
36 import org.apache.commons.io.IOUtils;
37 import org.junit.After;
38 import org.junit.Assert;
39 //import org.apache.commons.logging.Log;
40 //import org.apache.commons.logging.LogFactory;
41 import org.junit.Before;
42 import org.junit.Ignore;
43 import org.junit.Test;
44 import org.onap.policy.common.logging.flexlogger.FlexLogger;
45 import org.onap.policy.common.logging.flexlogger.Logger;
46 import org.onap.policy.pap.xacml.rest.components.PolicyDBDao.PolicyDBDaoTestClass;
47 import org.onap.policy.rest.XACMLRestProperties;
48 import org.onap.policy.rest.adapter.PolicyRestAdapter;
49 import org.onap.policy.rest.dao.PolicyDBException;
50 import org.onap.policy.rest.jpa.GroupEntity;
51 import org.onap.policy.rest.jpa.PdpEntity;
52 import org.onap.policy.rest.jpa.PolicyEntity;
53 import org.onap.policy.xacml.api.pap.OnapPDPGroup;
54 import org.onap.policy.xacml.std.pap.StdPDPGroup;
55 import org.onap.policy.xacml.util.XACMLPolicyWriter;
57 import com.att.research.xacml.util.XACMLProperties;
59 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
61 public class PolicyDBDaoTest {
63 private static Logger logger = FlexLogger.getLogger(PolicyDBDaoTest.class);
65 PolicyDBDaoTestClass d;
68 EntityManagerFactory emf;
71 System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME,"src/test/resources/xacml.pap.properties");
72 emf = Persistence.createEntityManagerFactory("testPapPU");
73 EntityManager em = emf.createEntityManager();
74 em.getTransaction().begin();
76 em.createQuery("DELETE FROM PolicyDBDaoEntity").executeUpdate();
77 em.createQuery("DELETE FROM PolicyEntity").executeUpdate();
78 em.createQuery("DELETE FROM ConfigurationDataEntity").executeUpdate();
79 em.createQuery("DELETE FROM ActionBodyEntity").executeUpdate();
80 em.createQuery("DELETE FROM PdpEntity").executeUpdate();
81 em.createQuery("DELETE FROM GroupEntity").executeUpdate();
83 em.getTransaction().commit();
85 logger.error("Exception Occured"+e);
86 em.getTransaction().rollback();
90 dbd = PolicyDBDao.getPolicyDBDaoInstance(emf);
91 dbd2 = PolicyDBDao.getPolicyDBDaoInstance(emf);
92 } catch (Exception e) {
93 //logger.error("Exception Occured"+e);
97 d = PolicyDBDao.getPolicyDBDaoTestClass();
101 public void cleanUp(){
102 EntityManager em = emf.createEntityManager();
103 em.getTransaction().begin();
105 em.createQuery("DELETE FROM PolicyDBDaoEntity").executeUpdate();
106 em.createQuery("DELETE FROM PolicyEntity").executeUpdate();
107 em.createQuery("DELETE FROM ConfigurationDataEntity").executeUpdate();
108 em.createQuery("DELETE FROM ActionBodyEntity").executeUpdate();
109 em.createQuery("DELETE FROM PdpEntity").executeUpdate();
110 em.createQuery("DELETE FROM GroupEntity").executeUpdate();
112 em.getTransaction().commit();
113 } catch(Exception e){
114 em.getTransaction().rollback();
118 FileUtils.forceDelete(new File("src/test/resources/junitTestCreatedDirectory"));
119 } catch (IOException e) {
126 public void computeScopeTest(){
127 Assert.assertEquals("com",d.computeScope("C:\\Users\\testuser\\admin\\repo\\com\\", "C:\\Users\\testuser\\admin\\repo"));
128 Assert.assertEquals("org.onap.policy",d.computeScope("/Users/testuser/admin/repo/org.onap.policy", "/Users/testuser/admin/repo"));
131 public void getConfigFileTest(){
132 PolicyRestAdapter pra = new PolicyRestAdapter();
133 pra.setConfigType(ConfigPolicy.JSON_CONFIG);
134 String configFile = d.getConfigFile("Config_mypolicy.xml", "org.onap", pra);
135 Assert.assertEquals("org.onap.Config_mypolicy.json", configFile);
136 //yes, we can do action files too even though they don't have configs
137 configFile = d.getConfigFile("Action_mypolicy.xml", "org.onap", pra);
138 Assert.assertEquals("org.onap.Action_mypolicy.json", configFile);
143 public void createFromPolicyObject(){
144 String workspaceDir = "src/test/resources/";
145 File parentPath = new File(workspaceDir+"/com");
146 Policy policyObject = new ConfigPolicy();
147 policyObject.policyAdapter = new PolicyRestAdapter();
148 policyObject.policyAdapter.setConfigName("testpolicy1");
149 policyObject.policyAdapter.setParentPath(parentPath.getAbsolutePath());
150 policyObject.policyAdapter.setPolicyDescription("my description");
151 policyObject.policyAdapter.setConfigBodyData("this is my test config file");
152 policyObject.policyAdapter.setPolicyName("testpolicy1");
153 policyObject.policyAdapter.setConfigType(ConfigPolicy.OTHER_CONFIG);
154 policyObject.policyAdapter.setPolicyType("Config");
155 policyObject.policyAdapter.setDomainDir("org.onap");
156 PolicyType policyTypeObject = new PolicyType();
157 policyObject.policyAdapter.setPolicyData(policyTypeObject);
158 PolicyDBDaoTransaction transaction = dbd.getNewTransaction();
160 transaction.createPolicy(policyObject, "testuser1");
161 transaction.commitTransaction();
162 } catch(Exception e){
163 transaction.rollbackTransaction();
167 EntityManager getData = emf.createEntityManager();
168 Query getDataQuery = getData.createQuery("SELECT p FROM PolicyEntity p WHERE p.scope=:scope AND p.policyName=:name");
169 getDataQuery.setParameter("scope", "org.onap");
170 getDataQuery.setParameter("name","Config_testpolicy1.xml");
171 PolicyEntity result = null;
173 result = (PolicyEntity)getDataQuery.getSingleResult();
174 } catch(Exception e){
175 logger.error("Exception Occured"+e);
180 expectedData = IOUtils.toString(XACMLPolicyWriter.getXmlAsInputStream(policyTypeObject));
181 } catch (IOException e1) {
184 Assert.assertEquals(expectedData, result.getPolicyData());
187 File policyFile = new File(workspaceDir+"/org/onap/Config_testpolicy1.xml");
189 transaction = dbd.getNewTransaction();
190 transaction.deletePolicy(policyFile.getAbsolutePath());
191 } catch(Exception e){
192 logger.error("Exception Occured"+e);
195 Assert.assertTrue(transaction.isTransactionOpen());
197 transaction.deletePolicy(policyFile.getAbsolutePath());
199 } catch(IllegalStateException e){
201 } catch(Exception e){
204 transaction.commitTransaction();
205 Assert.assertFalse(transaction.isTransactionOpen());
207 transaction = dbd.getNewTransaction();
208 transaction.deletePolicy(policyFile.getAbsolutePath());
209 } catch(Exception e){
210 logger.error("Exception Occured"+e);
213 //Assert.assertFalse(transaction.isTransactionOpen());
214 transaction.commitTransaction();
219 public void groupTransactions(){
220 PolicyDBDaoTransaction group = dbd.getNewTransaction();
221 String groupName = "test group 1";
223 group.createGroup(PolicyDBDao.createNewPDPGroupId(groupName), groupName, "this is a test group","testuser");
224 group.commitTransaction();
225 } catch(Exception e){
226 group.rollbackTransaction();
227 logger.error("Exception Occured"+e);
230 EntityManager em = emf.createEntityManager();
231 Query getGroup = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
232 getGroup.setParameter("groupId", PolicyDBDao.createNewPDPGroupId(groupName));
233 getGroup.setParameter("deleted", false);
234 List<?> groups = getGroup.getResultList();
235 if(groups.size() != 1){
238 GroupEntity groupEntity = (GroupEntity)groups.get(0);
240 Assert.assertEquals(groupName, groupEntity.getgroupName());
241 Assert.assertEquals("this is a test group", groupEntity.getDescription());
242 group = dbd.getNewTransaction();
244 OnapPDPGroup groupToDelete = new StdPDPGroup(PolicyDBDao.createNewPDPGroupId(groupName),Paths.get("/"));
245 group.deleteGroup(groupToDelete, null,"testuser");
246 group.commitTransaction();
247 } catch(Exception e){
248 group.rollbackTransaction();
249 logger.error("Exception Occured"+e);
252 em = emf.createEntityManager();
253 getGroup = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
254 getGroup.setParameter("groupId", PolicyDBDao.createNewPDPGroupId(groupName));
255 getGroup.setParameter("deleted", false);
256 groups = getGroup.getResultList();
257 if(groups.size() != 0){
258 System.out.println("Group size: "+groups.size());
262 //add a pdp to a group
263 group = dbd.getNewTransaction();
265 group.createGroup(PolicyDBDao.createNewPDPGroupId(groupName), groupName, "test group", "testuser");
266 group.commitTransaction();
267 } catch(Exception e){
268 group.rollbackTransaction();
269 logger.error("Exception Occured"+e);
272 group = dbd.getNewTransaction();
274 group.addPdpToGroup("http://localhost:4344/pdp/", PolicyDBDao.createNewPDPGroupId(groupName), "primary", "the main pdp", 3232, "testuser");
275 group.commitTransaction();
276 } catch(Exception e){
277 group.rollbackTransaction();
278 logger.error("Exception Occured"+e);
281 em = emf.createEntityManager();
282 Query getPdp = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted");
283 getPdp.setParameter("pdpId", "http://localhost:4344/pdp/");
284 getPdp.setParameter("deleted", false);
285 List<?> pdps = getPdp.getResultList();
286 if(pdps.size() != 1){
287 System.out.println("Group size: "+pdps.size());
290 PdpEntity pdp = (PdpEntity)pdps.get(0);
291 Assert.assertEquals(groupName, pdp.getGroup().getgroupName());
292 Assert.assertEquals(pdp.getPdpName(), "primary");
294 group = dbd.getNewTransaction();
296 group.removePdpFromGroup("http://localhost:4344/pdp/","testuser");
297 group.commitTransaction();
298 } catch(Exception e){
299 group.rollbackTransaction();
300 logger.error("Exception Occured"+e);
303 em = emf.createEntityManager();
304 getPdp = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted");
305 getPdp.setParameter("pdpId", "http://localhost:4344/pdp/");
306 getPdp.setParameter("deleted", false);
307 pdps = getPdp.getResultList();
308 if(pdps.size() != 0){
309 System.out.println("Group size: "+pdps.size());
314 //add some pdps to groups
315 group = dbd.getNewTransaction();
317 group.createGroup(PolicyDBDao.createNewPDPGroupId("testgroup1"), "testgroup1", "test group", "testuser");
318 group.commitTransaction();
319 } catch(Exception e){
320 group.rollbackTransaction();
321 logger.error("Exception Occured"+e);
324 group = dbd.getNewTransaction();
326 group.createGroup(PolicyDBDao.createNewPDPGroupId("testgroup2"), "testgroup2", "test group", "testuser");
327 group.commitTransaction();
328 } catch(Exception e){
329 group.rollbackTransaction();
330 logger.error("Exception Occured"+e);
334 group = dbd.getNewTransaction();
336 group.addPdpToGroup("http://localhost:4344/pdp/", PolicyDBDao.createNewPDPGroupId("testgroup1"), "primary", "the main pdp", 3232, "testuser");
337 group.commitTransaction();
338 } catch(Exception e){
339 group.rollbackTransaction();
340 logger.error("Exception Occured"+e);
343 group = dbd.getNewTransaction();
345 group.addPdpToGroup("http://localhost:4345/pdp/", PolicyDBDao.createNewPDPGroupId("testgroup1"), "secondary", "the second pdp", 3233, "testuser");
346 group.commitTransaction();
347 } catch(Exception e){
348 group.rollbackTransaction();
349 logger.error("Exception Occured"+e);
352 em = emf.createEntityManager();
353 getPdp = em.createQuery("SELECT p FROM PdpEntity p WHERE p.deleted=:deleted");
354 getPdp.setParameter("deleted", false);
355 pdps = getPdp.getResultList();
356 for(Object o : pdps){
357 Assert.assertEquals("testgroup1",((PdpEntity)o).getGroup().getgroupName());
361 group = dbd.getNewTransaction();
363 OnapPDPGroup groupToDelete = new StdPDPGroup(PolicyDBDao.createNewPDPGroupId("testgroup1"),Paths.get("/"));
364 OnapPDPGroup groupToMoveTo = new StdPDPGroup(PolicyDBDao.createNewPDPGroupId("testgroup2"),Paths.get("/"));
365 group.deleteGroup(groupToDelete, groupToMoveTo,"testuser");
366 group.commitTransaction();
367 } catch(Exception e){
368 group.rollbackTransaction();
369 logger.error("Exception Occured"+e);
372 em = emf.createEntityManager();
373 getGroup = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
374 getGroup.setParameter("groupId", "testgroup1");
375 getGroup.setParameter("deleted", false);
376 groups = getGroup.getResultList();
377 if(groups.size() != 0){
378 System.out.println("Group size: "+groups.size());
383 em = emf.createEntityManager();
384 getPdp = em.createQuery("SELECT p FROM PdpEntity p WHERE p.deleted=:deleted");
385 getPdp.setParameter("deleted", false);
386 pdps = getPdp.getResultList();
387 for(Object o : pdps){
388 Assert.assertEquals("testgroup2",((PdpEntity)o).getGroup().getgroupName());
392 group = dbd.getNewTransaction();
394 OnapPDPGroup groupToDelete = new StdPDPGroup(PolicyDBDao.createNewPDPGroupId("testgroup2"),Paths.get("/"));
395 OnapPDPGroup groupToMoveTo = null;
396 group.deleteGroup(groupToDelete, groupToMoveTo,"testuser");
397 group.commitTransaction();
399 } catch(PolicyDBException pe){
400 //good, can't delete group with pdps
401 group.rollbackTransaction();
402 } catch(Exception e){
403 group.rollbackTransaction();
404 logger.error("Exception Occured"+e);
409 //add policy to group
412 OnapPDPGroup pdpGroup = new StdPDPGroup("testgroup2", false, "newtestgroup2", "this is my new description", Paths.get("/"));
413 group = dbd.getNewTransaction();
415 group.updateGroup(pdpGroup, "testuser");
416 group.commitTransaction();
417 }catch (Exception e){
418 logger.error("Exception Occured"+e);
419 group.rollbackTransaction();
422 em = emf.createEntityManager();
423 getGroup = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
424 getGroup.setParameter("groupId", "newtestgroup2");
425 getGroup.setParameter("deleted", false);
426 groups = getGroup.getResultList();
427 if(groups.size() != 1){
428 System.out.println("Group size: "+groups.size());
432 em = emf.createEntityManager();
433 getGroup = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
434 getGroup.setParameter("groupId", "testgroup2");
435 getGroup.setParameter("deleted", false);
436 groups = getGroup.getResultList();
437 if(groups.size() != 0){
438 System.out.println("Group size: "+groups.size());
445 public void encryptionTest(){
447 String encr = d.encryptPassword("testpassword");
448 System.out.println("original password: "+"testpassword");
449 System.out.println("Encrypted password: "+encr);
450 String decr = d.decryptPassword(encr);
451 System.out.println("Decrypted password: "+decr);
452 Assert.assertEquals("testpassword", decr);
453 } catch (Exception e) {
454 logger.error("Exception Occured"+e);
460 public void getDescriptionFromXacmlTest(){
461 String myTestDesc = "hello this is a test";
462 String desc = d.getDescriptionFromXacml("<Description>"+myTestDesc+"</Description>");
463 Assert.assertEquals(myTestDesc, desc);
467 public void threadingStabilityTest(){
468 if(logger.isDebugEnabled()){
469 logger.debug("\n\n****************************"
470 + "threadingStabilityTest() entry"
471 + "******************************\n\n");
474 PolicyDBDaoTransaction t = dbd.getNewTransaction();
475 Assert.assertTrue(t.isTransactionOpen());
477 //Add 1000 ms to the timeout just to be sure it actually times out
478 int sleepTime = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_TIMEOUT)) + 1000;
479 if(logger.isDebugEnabled()){
480 Date date= new java.util.Date();
481 logger.debug("\n\nPolicyDBDaoTest.threadingStabilityTest() "
482 + "\n sleepTime = " + sleepTime
483 + "\n TimeStamp = " + date.getTime()
486 Thread.sleep(sleepTime);
487 } catch (InterruptedException e) {
488 logger.error("Exception Occured"+e);
490 if(logger.isDebugEnabled()){
491 Date date= new java.util.Date();
492 logger.debug("\n\nPolicyDBDaoTest.threadingStabilityTest() "
493 + "\n Assert.assertFalse(t.isTransactionOpen() = " + t.isTransactionOpen() + ")"
494 + "\n TimeStamp = " + date.getTime()
497 Assert.assertFalse(t.isTransactionOpen());
500 if(logger.isDebugEnabled()){
501 Date date= new java.util.Date();
502 logger.debug("\n\nPolicyDBDaoTest.threadingStabilityTest() "
503 + "\n a = dbd.getNewTransaction() "
504 + "\n TimeStamp = " + date.getTime()
507 PolicyDBDaoTransaction a = dbd.getNewTransaction();
508 if(logger.isDebugEnabled()){
509 Date date= new java.util.Date();
510 logger.debug("\n\nPolicyDBDaoTest.threadingStabilityTest() "
511 + "\n Assert.assertTrue(a.isTransactionOpen() = " + a.isTransactionOpen() + ")"
512 + "\n TimeStamp = " + date.getTime()
515 Assert.assertTrue(a.isTransactionOpen());
518 //Add 1000 ms to the timeout just to be sure it actually times out
519 int sleepTime = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_TIMEOUT)) + 1000;
520 if(logger.isDebugEnabled()){
521 Date date= new java.util.Date();
522 logger.debug("\n\nPolicyDBDaoTest.threadingStabilityTest() "
523 + "\n sleepTime = " + sleepTime
524 + "\n TimeStamp = " + date.getTime()
527 Thread.sleep(sleepTime);
528 } catch (InterruptedException e) {
529 logger.error("Exception Occured"+e);
531 if(logger.isDebugEnabled()){
532 Date date= new java.util.Date();
533 logger.debug("\n\nPolicyDBDaoTest.threadingStabilityTest() "
534 + "\n b = dbd.getNewTransaction() "
535 + "\n TimeStamp = " + date.getTime()
538 PolicyDBDaoTransaction b = dbd.getNewTransaction();
539 if(logger.isDebugEnabled()){
540 Date date= new java.util.Date();
541 logger.debug("\n\nPolicyDBDaoTest.threadingStabilityTest() "
542 + "\n Assert.assertFalse(a.isTransactionOpen() = " + a.isTransactionOpen() + ")"
543 + "\n TimeStamp = " + date.getTime()
546 Assert.assertFalse(a.isTransactionOpen());
547 if(logger.isDebugEnabled()){
548 Date date= new java.util.Date();
549 logger.debug("\n\nPolicyDBDaoTest.threadingStabilityTest() "
550 + "\n Assert.assertTrue(b.isTransactionOpen() = " + b.isTransactionOpen() + ")"
551 + "\n TimeStamp = " + date.getTime()
554 Assert.assertTrue(b.isTransactionOpen());
559 //Now let's test the transaction wait time timeout. Shorten the wait time to 1000 ms
560 System.setProperty(XACMLRestProperties.PROP_PAP_TRANS_WAIT,"1000");
561 //And let's lengthen the transaction timeout to 5000 ms
562 System.setProperty(XACMLRestProperties.PROP_PAP_TRANS_TIMEOUT,"5000");
564 PolicyDBDaoTransaction t1 = dbd.getNewTransaction();
565 if(logger.isDebugEnabled()){
566 Date date= new java.util.Date();
567 logger.debug("\n\nPolicyDBDaoTest.threadingStabilityTest() "
568 + "\n Assert.assertTrue(t1.isTransactionOpen() = " + t1.isTransactionOpen() + ")"
569 + "\n TimeStamp = " + date.getTime()
572 Assert.assertTrue(t1.isTransactionOpen());
573 //while it is open, get another from a different DB Dao so it will not collide on the synchronized code segment
574 //but will collide at the DB. Remember that the wait time is only 1000 ms
576 //Now the 2nd transaction has a wait timeout in 1000 ms
577 PolicyDBDaoTransaction t2 = dbd2.getNewTransaction();
579 * Give it plenty of time to time out the second transaction
580 * It will actually hang right here until it either gets the lock from the DB or the
581 * request for the DB lock times out. The timers are very sloppy so, I have given
582 * this plenty of leeway.
585 if(logger.isDebugEnabled()){
586 Date date= new java.util.Date();
587 logger.debug("\n\nPolicyDBDaoTest.threadingStabilityTest() "
588 + "\n Thread.sleep(3000)"
589 + "\n TimeStamp = " + date.getTime()
593 if(logger.isDebugEnabled()){
594 Date date= new java.util.Date();
595 logger.debug("\n\nPolicyDBDaoTest.threadingStabilityTest() "
596 + "\n Assert.assertTrue(t1.isTransactionOpen() = " + t1.isTransactionOpen() + ")"
597 + "\n Assert.assertFalse(t2.isTransactionOpen() = " + t2.isTransactionOpen() + ")"
598 + "\n TimeStamp = " + date.getTime()
601 //Assert.assertTrue(t1.isTransactionOpen());
602 //Assert.assertFalse(t2.isTransactionOpen());
604 Assert.fail("\n\nTransaction timeout of 1000 ms exceeded without a PersistenceException\n\n");
605 } catch (PersistenceException e) {
607 if(logger.isDebugEnabled()){
608 Date date= new java.util.Date();
609 logger.debug("\n\nPolicyDBDaoTest.threadingStabilityTest() "
610 + "\n SUCCESS! Transaction Wait Timeout worked!"
611 + "\n Caught PersistenceException = " + e
612 + "\n TimeStamp = " + date.getTime()
615 } catch (Exception e) {
616 // failure due to some other reason
617 if(logger.isDebugEnabled()){
618 Date date= new java.util.Date();
619 logger.debug("\n\nPolicyDBDaoTest.threadingStabilityTest() FAILURE"
620 + "\n Caught Exception = " + e
621 + "\n TimeStamp = " + date.getTime()
624 logger.error("Exception Occured"+e);
628 if(logger.isDebugEnabled()){
629 Date date= new java.util.Date();
630 logger.debug("\n\nthreadingStabilityTest() exit"
631 + "\n TimeStamp = " + date.getTime()