PageRenderTime 52ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/javatests/com/google/gerrit/server/rules/PrologTestCase.java

https://gitlab.com/chenfengxu/gerrit
Java | 189 lines | 143 code | 27 blank | 19 comment | 17 complexity | 850a746868e57c13dada0121c9c4c57d MD5 | raw file
  1. // Copyright (C) 2011 The Android Open Source Project
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package com.google.gerrit.server.rules;
  15. import static com.google.common.truth.Truth.assertThat;
  16. import static com.google.common.truth.Truth.assertWithMessage;
  17. import static java.nio.charset.StandardCharsets.UTF_8;
  18. import com.google.gerrit.common.TimeUtil;
  19. import com.google.gerrit.testing.GerritBaseTests;
  20. import com.google.inject.Guice;
  21. import com.google.inject.Module;
  22. import com.googlecode.prolog_cafe.exceptions.CompileException;
  23. import com.googlecode.prolog_cafe.lang.BufferingPrologControl;
  24. import com.googlecode.prolog_cafe.lang.JavaObjectTerm;
  25. import com.googlecode.prolog_cafe.lang.Prolog;
  26. import com.googlecode.prolog_cafe.lang.PrologClassLoader;
  27. import com.googlecode.prolog_cafe.lang.PrologMachineCopy;
  28. import com.googlecode.prolog_cafe.lang.StructureTerm;
  29. import com.googlecode.prolog_cafe.lang.SymbolTerm;
  30. import com.googlecode.prolog_cafe.lang.Term;
  31. import com.googlecode.prolog_cafe.lang.VariableTerm;
  32. import java.io.BufferedReader;
  33. import java.io.FileNotFoundException;
  34. import java.io.IOException;
  35. import java.io.InputStream;
  36. import java.io.InputStreamReader;
  37. import java.io.PushbackReader;
  38. import java.util.ArrayList;
  39. import java.util.Arrays;
  40. import java.util.List;
  41. import org.junit.Ignore;
  42. /** Base class for any tests written in Prolog. */
  43. @Ignore
  44. public abstract class PrologTestCase extends GerritBaseTests {
  45. private static final SymbolTerm test_1 = SymbolTerm.intern("test", 1);
  46. private String pkg;
  47. private boolean hasSetup;
  48. private boolean hasTeardown;
  49. private List<Term> tests;
  50. protected PrologMachineCopy machine;
  51. protected PrologEnvironment.Factory envFactory;
  52. protected void load(String pkg, String prologResource, Module... modules)
  53. throws CompileException, IOException {
  54. ArrayList<Module> moduleList = new ArrayList<>();
  55. moduleList.add(new PrologModule.EnvironmentModule());
  56. moduleList.addAll(Arrays.asList(modules));
  57. envFactory = Guice.createInjector(moduleList).getInstance(PrologEnvironment.Factory.class);
  58. PrologEnvironment env = envFactory.create(newMachine());
  59. consult(env, getClass(), prologResource);
  60. this.pkg = pkg;
  61. hasSetup = has(env, "setup");
  62. hasTeardown = has(env, "teardown");
  63. StructureTerm head =
  64. new StructureTerm(
  65. ":", SymbolTerm.intern(pkg), new StructureTerm(test_1, new VariableTerm()));
  66. tests = new ArrayList<>();
  67. for (Term[] pair : env.all(Prolog.BUILTIN, "clause", head, new VariableTerm())) {
  68. tests.add(pair[0]);
  69. }
  70. assertThat(tests).isNotEmpty();
  71. machine = PrologMachineCopy.save(env);
  72. }
  73. /**
  74. * Set up the Prolog environment.
  75. *
  76. * @param env Prolog environment.
  77. */
  78. protected void setUpEnvironment(PrologEnvironment env) throws Exception {}
  79. private PrologMachineCopy newMachine() {
  80. BufferingPrologControl ctl = new BufferingPrologControl();
  81. ctl.setMaxDatabaseSize(16 * 1024);
  82. ctl.setPrologClassLoader(new PrologClassLoader(getClass().getClassLoader()));
  83. return PrologMachineCopy.save(ctl);
  84. }
  85. protected void consult(BufferingPrologControl env, Class<?> clazz, String prologResource)
  86. throws CompileException, IOException {
  87. try (InputStream in = clazz.getResourceAsStream(prologResource)) {
  88. if (in == null) {
  89. throw new FileNotFoundException(prologResource);
  90. }
  91. SymbolTerm pathTerm = SymbolTerm.create(prologResource);
  92. JavaObjectTerm inTerm =
  93. new JavaObjectTerm(
  94. new PushbackReader(
  95. new BufferedReader(new InputStreamReader(in, UTF_8)), Prolog.PUSHBACK_SIZE));
  96. if (!env.execute(Prolog.BUILTIN, "consult_stream", pathTerm, inTerm)) {
  97. throw new CompileException("Cannot consult " + prologResource);
  98. }
  99. }
  100. }
  101. private boolean has(BufferingPrologControl env, String name) {
  102. StructureTerm head = SymbolTerm.create(pkg, name, 0);
  103. return env.execute(Prolog.BUILTIN, "clause", head, new VariableTerm());
  104. }
  105. public void runPrologBasedTests() throws Exception {
  106. int errors = 0;
  107. long start = TimeUtil.nowMs();
  108. for (Term test : tests) {
  109. PrologEnvironment env = envFactory.create(machine);
  110. setUpEnvironment(env);
  111. env.setEnabled(Prolog.Feature.IO, true);
  112. System.out.format("Prolog %-60s ...", removePackage(test));
  113. System.out.flush();
  114. if (hasSetup) {
  115. call(env, "setup");
  116. }
  117. List<Term> all = env.all(Prolog.BUILTIN, "call", test);
  118. if (hasTeardown) {
  119. call(env, "teardown");
  120. }
  121. System.out.println(all.size() == 1 ? "OK" : "FAIL");
  122. if (all.size() > 0 && !test.equals(all.get(0))) {
  123. for (Term t : all) {
  124. Term head = ((StructureTerm) removePackage(t)).args()[0];
  125. Term[] args = ((StructureTerm) head).args();
  126. System.out.print(" Result: ");
  127. for (int i = 0; i < args.length; i++) {
  128. if (0 < i) {
  129. System.out.print(", ");
  130. }
  131. System.out.print(args[i]);
  132. }
  133. System.out.println();
  134. }
  135. System.out.println();
  136. }
  137. if (all.size() != 1) {
  138. errors++;
  139. }
  140. }
  141. long end = TimeUtil.nowMs();
  142. System.out.println("-------------------------------");
  143. System.out.format(
  144. "Prolog tests: %d, Failures: %d, Time elapsed %.3f sec",
  145. tests.size(), errors, (end - start) / 1000.0);
  146. System.out.println();
  147. assertThat(errors).isEqualTo(0);
  148. }
  149. private void call(BufferingPrologControl env, String name) {
  150. StructureTerm head = SymbolTerm.create(pkg, name, 0);
  151. assertWithMessage("Cannot invoke " + pkg + ":" + name)
  152. .that(env.execute(Prolog.BUILTIN, "call", head))
  153. .isTrue();
  154. }
  155. private Term removePackage(Term test) {
  156. Term name = test;
  157. if (name instanceof StructureTerm && ":".equals(name.name())) {
  158. name = name.arg(1);
  159. }
  160. return name;
  161. }
  162. }