project.setUserProperty(key, all.getProperty(key));\r
}\r
}\r
-\r
- /*\r
- Properties rootProps = loadFile(slcRootFile.getAbsolutePath());\r
-\r
- final File confDir;\r
- final File workDir;\r
- // Root dir\r
- final File rootDir = slcRootFile.getParentFile();\r
- project.setUserProperty(ROOT_DIR_PROPERTY, rootDir.getAbsolutePath());\r
-\r
- // Conf dir\r
- if (project.getUserProperty(CONF_DIR_PROPERTY) == null) {\r
- confDir = new File(rootProps.getProperty(CONF_DIR_PROPERTY, rootDir\r
- .getAbsolutePath()\r
- + "/../conf")).getAbsoluteFile();\r
- project.setUserProperty(CONF_DIR_PROPERTY, confDir\r
- .getAbsolutePath());\r
- } else {\r
- confDir = new File(project.getUserProperty(CONF_DIR_PROPERTY))\r
- .getAbsoluteFile();\r
- }\r
-\r
- // Work dir\r
- if (project.getUserProperty(WORK_DIR_PROPERTY) == null) {\r
- workDir = new File(rootProps.getProperty(WORK_DIR_PROPERTY, rootDir\r
- .getAbsolutePath()\r
- + "/../work")).getAbsoluteFile();\r
- project.setUserProperty(WORK_DIR_PROPERTY, workDir\r
- .getAbsolutePath());\r
- } else {\r
- workDir = new File(project.getUserProperty(WORK_DIR_PROPERTY))\r
- .getAbsoluteFile();\r
- }\r
-\r
- // Properties from the conf dir files\r
- Properties properties = new Properties();\r
- StringTokenizer st = new StringTokenizer(rootProps.getProperty(\r
- PROPERTY_FILE_NAMES_PROPERTY, "slc.properties"), ",");\r
- while (st.hasMoreTokens()) {\r
- String fileName = st.nextToken();\r
- properties.putAll(loadFile(confDir.getAbsolutePath() + "/"\r
- + fileName));\r
- }\r
-\r
- for (Object o : properties.keySet()) {\r
- String key = o.toString();\r
- if (project.getUserProperty(key) == null) {// not already set\r
- project.setUserProperty(key, properties.getProperty(key));\r
- }\r
- }\r
-\r
- // Default application context\r
- if (project.getUserProperty(APPLICATION_CONTEXT_PROPERTY) == null) {\r
- project.setUserProperty(APPLICATION_CONTEXT_PROPERTY, confDir\r
- .getAbsolutePath()\r
- + "/applicationContext.xml");\r
- }\r
- // Default test run\r
- if (project.getUserProperty(DEFAULT_TEST_RUN_PROPERTY) == null) {\r
- project\r
- .setUserProperty(DEFAULT_TEST_RUN_PROPERTY,\r
- "defaultTestRun");\r
- }\r
- */\r
}\r
\r
public static Properties prepareAllProperties() {\r
- Properties all = new Properties();\r
- all.putAll(System.getProperties());\r
+ try {\r
+ Properties all = new Properties();\r
+ all.putAll(System.getProperties());\r
\r
- if (all.getProperty(ROOT_FILE_PROPERTY) == null) {\r
- throw new RuntimeException("System Property " + ROOT_FILE_PROPERTY\r
- + " has to be set.");\r
- }\r
+ if (all.getProperty(ROOT_FILE_PROPERTY) == null) {\r
+ throw new RuntimeException("System Property "\r
+ + ROOT_FILE_PROPERTY + " has to be set.");\r
+ }\r
\r
- File slcRootFile = new File(all.getProperty(ROOT_FILE_PROPERTY))\r
- .getAbsoluteFile();\r
- Properties rootProps = loadFile(slcRootFile.getAbsolutePath());\r
-\r
- final File confDir;\r
- final File workDir;\r
- // Root dir\r
- final File rootDir = slcRootFile.getParentFile();\r
- all.setProperty(ROOT_DIR_PROPERTY, rootDir.getAbsolutePath());\r
-\r
- // Conf dir\r
- if (all.getProperty(CONF_DIR_PROPERTY) == null) {\r
- confDir = new File(rootProps.getProperty(CONF_DIR_PROPERTY, rootDir\r
- .getAbsolutePath()\r
- + "/../conf")).getAbsoluteFile();\r
- all.setProperty(CONF_DIR_PROPERTY, confDir.getAbsolutePath());\r
- } else {\r
- confDir = new File(all.getProperty(CONF_DIR_PROPERTY))\r
+ File slcRootFile = new File(all.getProperty(ROOT_FILE_PROPERTY))\r
.getAbsoluteFile();\r
- }\r
+ Properties rootProps = loadFile(slcRootFile.getAbsolutePath());\r
+\r
+ final File confDir;\r
+ final File workDir;\r
+ // Root dir\r
+ final File rootDir = slcRootFile.getParentFile();\r
+ all.setProperty(ROOT_DIR_PROPERTY, rootDir.getCanonicalPath());\r
+\r
+ // Conf dir\r
+ if (all.getProperty(CONF_DIR_PROPERTY) == null) {\r
+ confDir = new File(rootProps.getProperty(CONF_DIR_PROPERTY,\r
+ rootDir.getAbsolutePath() + "/../conf"))\r
+ .getCanonicalFile();\r
+ all.setProperty(CONF_DIR_PROPERTY, confDir.getAbsolutePath());\r
+ } else {\r
+ confDir = new File(all.getProperty(CONF_DIR_PROPERTY))\r
+ .getCanonicalFile();\r
+ }\r
\r
- // Work dir\r
- if (all.getProperty(WORK_DIR_PROPERTY) == null) {\r
- workDir = new File(rootProps.getProperty(WORK_DIR_PROPERTY, rootDir\r
- .getAbsolutePath()\r
- + "/../work")).getAbsoluteFile();\r
- all.setProperty(WORK_DIR_PROPERTY, workDir.getAbsolutePath());\r
- } else {\r
- workDir = new File(all.getProperty(WORK_DIR_PROPERTY))\r
- .getAbsoluteFile();\r
- }\r
+ // Work dir\r
+ if (all.getProperty(WORK_DIR_PROPERTY) == null) {\r
+ workDir = new File(rootProps.getProperty(WORK_DIR_PROPERTY,\r
+ rootDir.getAbsolutePath() + "/../work"))\r
+ .getCanonicalFile();\r
+ all.setProperty(WORK_DIR_PROPERTY, workDir.getAbsolutePath());\r
+ } else {\r
+ workDir = new File(all.getProperty(WORK_DIR_PROPERTY))\r
+ .getCanonicalFile();\r
+ }\r
\r
- // Properties from the conf dir files\r
- Properties properties = new Properties();\r
- StringTokenizer st = new StringTokenizer(rootProps.getProperty(\r
- PROPERTY_FILE_NAMES_PROPERTY, "slc.properties"), ",");\r
- while (st.hasMoreTokens()) {\r
- String fileName = st.nextToken();\r
- properties.putAll(loadFile(confDir.getAbsolutePath() + "/"\r
- + fileName));\r
- }\r
+ // Properties from the conf dir files\r
+ Properties properties = new Properties();\r
+ StringTokenizer st = new StringTokenizer(rootProps.getProperty(\r
+ PROPERTY_FILE_NAMES_PROPERTY, "slc.properties"), ",");\r
+ while (st.hasMoreTokens()) {\r
+ String fileName = st.nextToken();\r
+ properties.putAll(loadFile(confDir.getAbsolutePath() + "/"\r
+ + fileName));\r
+ }\r
\r
- for (Object o : properties.keySet()) {\r
- String key = o.toString();\r
- if (all.getProperty(key) == null) {// not already set\r
- all.setProperty(key, properties.getProperty(key));\r
+ for (Object o : properties.keySet()) {\r
+ String key = o.toString();\r
+ if (all.getProperty(key) == null) {// not already set\r
+ all.setProperty(key, properties.getProperty(key));\r
+ }\r
}\r
- }\r
\r
- // Default application context\r
- if (all.getProperty(APPLICATION_CONTEXT_PROPERTY) == null) {\r
- all.setProperty(APPLICATION_CONTEXT_PROPERTY, confDir\r
- .getAbsolutePath()\r
- + "/applicationContext.xml");\r
- }\r
- // Default test run\r
- if (all.getProperty(DEFAULT_TEST_RUN_PROPERTY) == null) {\r
- all.setProperty(DEFAULT_TEST_RUN_PROPERTY, "defaultTestRun");\r
- }\r
+ // Default application context\r
+ if (all.getProperty(APPLICATION_CONTEXT_PROPERTY) == null) {\r
+ all.setProperty(APPLICATION_CONTEXT_PROPERTY, confDir\r
+ .getAbsolutePath()\r
+ + "/applicationContext.xml");\r
+ }\r
+ // Default test run\r
+ if (all.getProperty(DEFAULT_TEST_RUN_PROPERTY) == null) {\r
+ all.setProperty(DEFAULT_TEST_RUN_PROPERTY, "defaultTestRun");\r
+ }\r
\r
- return all;\r
+ return all;\r
+ } catch (Exception e) {\r
+ throw new SlcAntException("Unexpected exception while configuring",\r
+ e);\r
+ }\r
}\r
\r
public static Properties loadFile(String path) {\r
-slc.test=org.argeo.slc.ant.test.SlcTestTask
\ No newline at end of file
+slc.test=org.argeo.slc.ant.test.SlcTestTask\r
+slc.closeResult=org.argeo.slc.ant.test.SlcCloseTestResultTask\r
--- /dev/null
+package org.argeo.slc.ant.test;\r
+\r
+import org.argeo.slc.ant.spring.AbstractSpringTask;\r
+import org.argeo.slc.core.test.TestReport;\r
+import org.argeo.slc.core.test.TestResult;\r
+\r
+public class SlcCloseTestResultTask extends AbstractSpringTask {\r
+ private String result;\r
+ private String report;\r
+ \r
+ public void execute(){\r
+ TestResult testResult = (TestResult)getContext().getBean(result);\r
+ testResult.close();\r
+ \r
+ if(report!=null){\r
+ TestReport testReport = (TestReport)getContext().getBean(report);\r
+ testReport.generateTestReport(testResult);\r
+ }\r
+ }\r
+\r
+ public void setResult(String bean) {\r
+ this.result = bean;\r
+ }\r
+\r
+ public void setReport(String report) {\r
+ this.report = report;\r
+ }\r
+ \r
+ \r
+}\r
\r
public class SimpleResultPart implements TestResultPart {\r
\r
- public final static Integer PASSED = 1;\r
- public final static Integer FAILED = 2;\r
- public final static Integer ERROR = 3;\r
+ public final static int PASSED = 1;\r
+ public final static int FAILED = 2;\r
+ public final static int ERROR = 3;\r
\r
/** For ORM */\r
private Long tid;\r
--- /dev/null
+package org.argeo.slc.core.test;\r
+\r
+public interface TestReport {\r
+ public void generateTestReport(TestResult result);\r
+}\r
public interface TestResult {\r
public TestResultId getTestResultId();\r
public void addResultPart(TestResultPart part);\r
+ public void close();\r
}\r
public interface TestResultListener {\r
public void resultPartAdded(TestResult testResult,\r
TestResultPart testResultPart);\r
+ public void close();\r
}\r
partStructs.notifyAll();\r
}\r
}\r
+ \r
+ /** Finish the remaining and destroy*/\r
+ public void close(){\r
+ synchronized (partStructs) {\r
+ // TODO: put a timeout\r
+ while (partStructs.size() != 0) {\r
+ try {\r
+ partStructs.wait();\r
+ } catch (InterruptedException e) {\r
+ // silent\r
+ }\r
+ }\r
+ destroy();\r
+ }\r
+ }\r
\r
public final void resultPartAdded(TestResult testResult,\r
TestResultPart testResultPart) {\r
}\r
}\r
\r
+ protected abstract void resultPartAdded(PartStruct partStruct);\r
+\r
public void run() {\r
while (thread != null) {\r
synchronized (partStructs) {\r
}\r
\r
partStructs.clear();\r
+ partStructs.notifyAll();\r
while (partStructs.size() == 0) {\r
try {\r
partStructs.wait();\r
}\r
}\r
\r
- protected abstract void resultPartAdded(PartStruct partStruct);\r
\r
protected static class PartStruct {\r
public final TreeSPath path;\r
--- /dev/null
+package org.argeo.slc.core.test.tree;\r
+\r
+import java.io.File;\r
+import java.io.FileWriter;\r
+import java.io.IOException;\r
+import java.util.List;\r
+\r
+import org.argeo.slc.core.structure.tree.TreeSPath;\r
+import org.argeo.slc.core.test.SimpleResultPart;\r
+import org.argeo.slc.core.test.TestReport;\r
+import org.argeo.slc.core.test.TestResult;\r
+import org.argeo.slc.core.test.TestResultPart;\r
+import org.argeo.slc.dao.test.TestResultDao;\r
+\r
+public class FullHtmlTreeReport implements TestReport {\r
+ private TestResultDao testResultDao;\r
+ private File reportDir;\r
+\r
+ public void generateTestReport(TestResult testResult) {\r
+ if (testResultDao == null) {\r
+ TreeTestResult result = (TreeTestResult) testResult;\r
+ generateResultPage(getResultFile(result), result);\r
+ } else {\r
+ if (reportDir.exists()) {\r
+ // clean\r
+ for (File file : reportDir.listFiles()) {\r
+ file.delete();\r
+ }\r
+ }\r
+ reportDir.mkdirs();\r
+\r
+ StringBuffer index = new StringBuffer("");\r
+ index\r
+ .append("<html><header><title>Results</title></header><body>\n<table border=1>\n");\r
+\r
+ List<TestResult> list = testResultDao.listTestResults();\r
+ for (TestResult testRes : list) {\r
+ TreeTestResult res = (TreeTestResult) testRes;\r
+\r
+ File file = getResultFile(res);\r
+ index.append("<tr><td><a href=\"").append(file.getName())\r
+ .append("\">");\r
+ index.append(res.getTestResultId()).append("</a></td></tr>\n");\r
+ generateResultPage(file, res);\r
+ }\r
+\r
+ index.append("</table>\n</body></html>");\r
+\r
+ try {\r
+ FileWriter writer = new FileWriter(reportDir.getPath()\r
+ + File.separator + "index.html");\r
+ writer.write(index.toString());\r
+ writer.close();\r
+ } catch (IOException e) {\r
+ e.printStackTrace();\r
+ }\r
+\r
+ }\r
+ }\r
+\r
+ protected void generateResultPage(File file, TreeTestResult result) {\r
+ StringBuffer buf = new StringBuffer("");\r
+ buf.append("<html>\n");\r
+ buf.append("<header><title>Result #").append(result.getTestResultId())\r
+ .append("</title></header>\n");\r
+\r
+ buf.append("<body>\n");\r
+\r
+ buf.append("<h1>Result #").append(result.getTestResultId()).append(\r
+ "</h1>\n");\r
+\r
+ buf.append("<table border=1>\n");\r
+ for (TreeSPath path : result.getResultParts().keySet()) {\r
+ buf.append("<tr><td>").append(path).append("</td>\n");\r
+ buf.append("<td>");\r
+ PartSubList subList = (PartSubList) result.getResultParts().get(\r
+ path);\r
+ buf.append("<table border=0>\n");\r
+ for (TestResultPart part : subList.getParts()) {\r
+ SimpleResultPart sPart = (SimpleResultPart) part;\r
+ String color = "yellow";\r
+ if (sPart.getStatus() == SimpleResultPart.PASSED) {\r
+ color = "green";\r
+ } else {\r
+ color = "red";\r
+ }\r
+ buf.append("<tr><td style=\"color:").append(color)\r
+ .append("\">");\r
+\r
+ buf.append(sPart.getMessage());\r
+ buf.append("</td></tr>\n");\r
+ }\r
+ buf.append("</table>\n");\r
+\r
+ buf.append("</td></tr>\n");\r
+ }\r
+ buf.append("</table>\n");\r
+\r
+ buf.append("</body>");\r
+ buf.append("</html>");\r
+\r
+ try {\r
+ FileWriter writer = new FileWriter(file);\r
+ writer.write(buf.toString());\r
+ writer.close();\r
+ } catch (IOException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ protected File getResultFile(TreeTestResult result) {\r
+ return new File(reportDir.getPath() + File.separator\r
+ + result.getTestResultId() + ".html");\r
+ }\r
+\r
+ public void setTestResultDao(TestResultDao testResultDao) {\r
+ this.testResultDao = testResultDao;\r
+ }\r
+\r
+ public void setReportDir(File reportDir) {\r
+ this.reportDir = reportDir;\r
+ }\r
+\r
+}\r
\r
private SortedMap<TreeSPath, PartSubList> resultParts = new TreeMap<TreeSPath, PartSubList>();\r
\r
-\r
- \r
public TestResultId getTestResultId() {\r
return testResultId;\r
}\r
subList.getParts().add(part);\r
\r
// notify listeners\r
- for (TestResultListener listener : listeners) {\r
- listener.resultPartAdded(this, part);\r
+ synchronized (listeners) {\r
+ for (TestResultListener listener : listeners) {\r
+ listener.resultPartAdded(this, part);\r
+ }\r
}\r
}\r
\r
this.resultParts = resultParts;\r
}\r
\r
+ public void close() {\r
+ synchronized (listeners) {\r
+ for (TestResultListener listener : listeners) {\r
+ listener.close();\r
+ }\r
+ listeners.clear();\r
+ }\r
+ }\r
+\r
Long getTid() {\r
return tid;\r
}\r
package org.argeo.slc.core.test.tree;\r
\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+\r
import org.argeo.slc.dao.test.TestResultDao;\r
\r
public class TreeTestResultPersister extends AsynchronousTreeTestResultListener {\r
+ private static Log log = LogFactory.getLog(TreeTestResultPersister.class);\r
+\r
private TestResultDao testResultDao;\r
\r
@Override\r
protected void resultPartAdded(PartStruct partStruct) {\r
- TreeTestResult persistedResult = (TreeTestResult) testResultDao\r
- .getTestResult(partStruct.resultId);\r
- if (persistedResult == null) {\r
- persistedResult = new TreeTestResult();\r
- persistedResult.setNumericResultId(partStruct.resultId);\r
- PartSubList subList = new PartSubList();\r
- subList.getParts().add(partStruct.part);\r
- persistedResult.getResultParts().put(partStruct.path, subList);\r
-\r
- testResultDao.create(persistedResult);\r
- } else {\r
- PartSubList subList = persistedResult.getResultParts().get(\r
- partStruct.path);\r
- if (subList == null) {\r
- subList = new PartSubList();\r
+ try {\r
+ TreeTestResult persistedResult = (TreeTestResult) testResultDao\r
+ .getTestResult(partStruct.resultId);\r
+ if (persistedResult == null) {\r
+ persistedResult = new TreeTestResult();\r
+ persistedResult.setNumericResultId(partStruct.resultId);\r
+ PartSubList subList = new PartSubList();\r
+ subList.getParts().add(partStruct.part);\r
persistedResult.getResultParts().put(partStruct.path, subList);\r
- }\r
- subList.getParts().add(partStruct.part);\r
\r
- testResultDao.update(persistedResult);\r
+ testResultDao.create(persistedResult);\r
+ } else {\r
+ PartSubList subList = persistedResult.getResultParts().get(\r
+ partStruct.path);\r
+ if (subList == null) {\r
+ subList = new PartSubList();\r
+ persistedResult.getResultParts().put(partStruct.path,\r
+ subList);\r
+ }\r
+ persistedResult.getResultParts().get(partStruct.path)\r
+ .getParts().add(partStruct.part);\r
+\r
+ if (log.isTraceEnabled()) {\r
+ log.trace("ResultId:" + persistedResult.getTestResultId());\r
+ log.trace("ResultParts size:"\r
+ + persistedResult.getResultParts().size());\r
+ log.trace("Sublist size:" + subList.getParts().size());\r
+ log.trace("Part: " + partStruct.part);\r
+ }\r
+ testResultDao.update(persistedResult);\r
+ }\r
+ } catch (Exception e) {\r
+ log.error("Could not persist part for result #"\r
+ + partStruct.resultId, e);\r
}\r
}\r
\r
<id name="tid" column="T_ID">\r
<generator class="native" />\r
</id>\r
- <list name="parts" table="SUB_LIST_PARTS" cascade="all" lazy="false">\r
- <key column="PARENT_ID" unique="true" />\r
- <list-index column="INDEX" />\r
- <many-to-many\r
- class="org.argeo.slc.core.test.SimpleResultPart" column="PART_ID" lazy="false"/>\r
+ <list name="parts" cascade="all" lazy="false">\r
+ <key column="PART_SUBLIST_ID" />\r
+ <list-index column="INDX" />\r
+\r
+ <one-to-many\r
+ class="org.argeo.slc.core.test.SimpleResultPart" />\r
</list>\r
</class>\r
</hibernate-mapping>
\ No newline at end of file
String[] args = { data.getInputFile().getAbsolutePath(),\r
data.getReachedFile().getAbsolutePath() };\r
\r
- // execute\r
- log.info("Execute example appli...");\r
- appli.filter(args);\r
-\r
TestResult result = testRun.getTestResult();\r
+\r
+ SimpleResultPart executePart = new SimpleResultPart();\r
+ executePart.setMessage("Execute example appli");\r
+ try {\r
+ // execute\r
+ log.info("Execute example appli...");\r
+ appli.filter(args);\r
+ \r
+ executePart.setStatus(SimpleResultPart.PASSED);\r
+ } catch (Exception e) {\r
+ executePart.setStatus(SimpleResultPart.ERROR);\r
+ executePart.setException(e);\r
+ }\r
+ result.addResultPart(executePart);\r
+ if(executePart.getStatus()==SimpleResultPart.ERROR){\r
+ return;\r
+ }\r
+\r
result.addResultPart(assertFiles(data));\r
}\r
\r
+ "/root/Category1/SubCategory2/build.xml");\r
AntRegistryUtil.runAll(antFile);\r
\r
- try {\r
- Thread.sleep(5000);\r
- } catch (InterruptedException e) {\r
- e.printStackTrace();\r
- }\r
}\r
}\r
<!-- Results -->\r
<bean id="dataSourceResults"\r
class="org.springframework.jdbc.datasource.DriverManagerDataSource"\r
- destroy-method="close">\r
+ >\r
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />\r
<property name="url"\r
- value="jdbc:hsqldb:file:${slc.workDir}/results/hsqldb/db" />\r
+ value="jdbc:hsqldb:file:${slc.workDir}/results/hsqldb/db;shutdown=true" />\r
<property name="username" value="sa" />\r
<property name="password" value="" />\r
</bean>\r
<property name="hibernateProperties">\r
<value>\r
hibernate.dialect=org.hibernate.dialect.HSQLDialect\r
- c3p0.min_size=1 c3p0.timeout=1800\r
cache.provider_class=org.hibernate.cache.NoCacheProvider\r
- cache.use_query_cache=false cache.use_minimal_puts=false\r
- max_fetch_depth=3 show_sql=true format_sql=true\r
+ cache.use_query_cache=false\r
+ cache.use_minimal_puts=false\r
+ max_fetch_depth=3\r
current_session_context_class=thread\r
hibernate.hbm2ddl.auto=update\r
</value>\r
<property name="sessionFactory" ref="sessionFactoryResults" />\r
</bean>\r
\r
+ <bean id="report"\r
+ class="org.argeo.slc.core.test.tree.FullHtmlTreeReport">\r
+ <property name="testResultDao" ref="testResultDao" />\r
+ <property name="reportDir" value="${slc.workDir}/results/report" />\r
+ </bean>\r
\r
+ \r
</beans>
\ No newline at end of file
# Set root logger level to DEBUG and its only appender to A1.\r
-log4j.rootLogger=DEBUG, console\r
+log4j.rootLogger=INFO, console\r
\r
## Levels\r
+# Slc\r
+log4j.logger.org.argeo.slc=INFO\r
# Spring\r
log4j.logger.org.springframework=INFO\r
# Hibernate\r
-log4j.logger.org.hibernate=INFO\r
+log4j.logger.org.hibernate=WARN\r
+#log4j.logger.org.hibernate.SQL=TRACE\r
+#log4j.logger.org.hibernate.tool.hbm2ddl=TRACE\r
+#log4j.logger.org.hibernate.type=TRACE\r
\r
\r
## Appenders\r
<testData bean="testData.eu-reform" />\r
</slc.test>\r
\r
+ <slc.closeResult result="testResult" report="report"/>\r
</target>\r
\r
</project>
\ No newline at end of file
They are determined to safeguard the freedom, common heritage and civilisation of their peoples, founded on the principles of democracy, individual liberty and the rule of law. They seek to promote stability and well-being in the North Atlantic area.\r
\r
They are resolved to unite their efforts for collective defence and for the preservation of peace and security. They therefore agree to this North Atlantic Treaty :\r
-Article 1\r
+Article 1CHANGE\r
\r
The Parties undertake, as set forth in the Charter of the United Nations, to settle any international dispute in which they may be involved by peaceful means in such a manner that international peace and security and justice are not endangered, and to refrain in their international relations from the threat or use of force in any manner inconsistent with the purposes of the United Nations.\r
Article 2\r