/javatests/com/google/gerrit/server/rules/PrologTestCase.java
Java | 189 lines | 143 code | 27 blank | 19 comment | 17 complexity | 850a746868e57c13dada0121c9c4c57d MD5 | raw file
- // Copyright (C) 2011 The Android Open Source Project
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package com.google.gerrit.server.rules;
- import static com.google.common.truth.Truth.assertThat;
- import static com.google.common.truth.Truth.assertWithMessage;
- import static java.nio.charset.StandardCharsets.UTF_8;
- import com.google.gerrit.common.TimeUtil;
- import com.google.gerrit.testing.GerritBaseTests;
- import com.google.inject.Guice;
- import com.google.inject.Module;
- import com.googlecode.prolog_cafe.exceptions.CompileException;
- import com.googlecode.prolog_cafe.lang.BufferingPrologControl;
- import com.googlecode.prolog_cafe.lang.JavaObjectTerm;
- import com.googlecode.prolog_cafe.lang.Prolog;
- import com.googlecode.prolog_cafe.lang.PrologClassLoader;
- import com.googlecode.prolog_cafe.lang.PrologMachineCopy;
- import com.googlecode.prolog_cafe.lang.StructureTerm;
- import com.googlecode.prolog_cafe.lang.SymbolTerm;
- import com.googlecode.prolog_cafe.lang.Term;
- import com.googlecode.prolog_cafe.lang.VariableTerm;
- import java.io.BufferedReader;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.PushbackReader;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.List;
- import org.junit.Ignore;
- /** Base class for any tests written in Prolog. */
- @Ignore
- public abstract class PrologTestCase extends GerritBaseTests {
- private static final SymbolTerm test_1 = SymbolTerm.intern("test", 1);
- private String pkg;
- private boolean hasSetup;
- private boolean hasTeardown;
- private List<Term> tests;
- protected PrologMachineCopy machine;
- protected PrologEnvironment.Factory envFactory;
- protected void load(String pkg, String prologResource, Module... modules)
- throws CompileException, IOException {
- ArrayList<Module> moduleList = new ArrayList<>();
- moduleList.add(new PrologModule.EnvironmentModule());
- moduleList.addAll(Arrays.asList(modules));
- envFactory = Guice.createInjector(moduleList).getInstance(PrologEnvironment.Factory.class);
- PrologEnvironment env = envFactory.create(newMachine());
- consult(env, getClass(), prologResource);
- this.pkg = pkg;
- hasSetup = has(env, "setup");
- hasTeardown = has(env, "teardown");
- StructureTerm head =
- new StructureTerm(
- ":", SymbolTerm.intern(pkg), new StructureTerm(test_1, new VariableTerm()));
- tests = new ArrayList<>();
- for (Term[] pair : env.all(Prolog.BUILTIN, "clause", head, new VariableTerm())) {
- tests.add(pair[0]);
- }
- assertThat(tests).isNotEmpty();
- machine = PrologMachineCopy.save(env);
- }
- /**
- * Set up the Prolog environment.
- *
- * @param env Prolog environment.
- */
- protected void setUpEnvironment(PrologEnvironment env) throws Exception {}
- private PrologMachineCopy newMachine() {
- BufferingPrologControl ctl = new BufferingPrologControl();
- ctl.setMaxDatabaseSize(16 * 1024);
- ctl.setPrologClassLoader(new PrologClassLoader(getClass().getClassLoader()));
- return PrologMachineCopy.save(ctl);
- }
- protected void consult(BufferingPrologControl env, Class<?> clazz, String prologResource)
- throws CompileException, IOException {
- try (InputStream in = clazz.getResourceAsStream(prologResource)) {
- if (in == null) {
- throw new FileNotFoundException(prologResource);
- }
- SymbolTerm pathTerm = SymbolTerm.create(prologResource);
- JavaObjectTerm inTerm =
- new JavaObjectTerm(
- new PushbackReader(
- new BufferedReader(new InputStreamReader(in, UTF_8)), Prolog.PUSHBACK_SIZE));
- if (!env.execute(Prolog.BUILTIN, "consult_stream", pathTerm, inTerm)) {
- throw new CompileException("Cannot consult " + prologResource);
- }
- }
- }
- private boolean has(BufferingPrologControl env, String name) {
- StructureTerm head = SymbolTerm.create(pkg, name, 0);
- return env.execute(Prolog.BUILTIN, "clause", head, new VariableTerm());
- }
- public void runPrologBasedTests() throws Exception {
- int errors = 0;
- long start = TimeUtil.nowMs();
- for (Term test : tests) {
- PrologEnvironment env = envFactory.create(machine);
- setUpEnvironment(env);
- env.setEnabled(Prolog.Feature.IO, true);
- System.out.format("Prolog %-60s ...", removePackage(test));
- System.out.flush();
- if (hasSetup) {
- call(env, "setup");
- }
- List<Term> all = env.all(Prolog.BUILTIN, "call", test);
- if (hasTeardown) {
- call(env, "teardown");
- }
- System.out.println(all.size() == 1 ? "OK" : "FAIL");
- if (all.size() > 0 && !test.equals(all.get(0))) {
- for (Term t : all) {
- Term head = ((StructureTerm) removePackage(t)).args()[0];
- Term[] args = ((StructureTerm) head).args();
- System.out.print(" Result: ");
- for (int i = 0; i < args.length; i++) {
- if (0 < i) {
- System.out.print(", ");
- }
- System.out.print(args[i]);
- }
- System.out.println();
- }
- System.out.println();
- }
- if (all.size() != 1) {
- errors++;
- }
- }
- long end = TimeUtil.nowMs();
- System.out.println("-------------------------------");
- System.out.format(
- "Prolog tests: %d, Failures: %d, Time elapsed %.3f sec",
- tests.size(), errors, (end - start) / 1000.0);
- System.out.println();
- assertThat(errors).isEqualTo(0);
- }
- private void call(BufferingPrologControl env, String name) {
- StructureTerm head = SymbolTerm.create(pkg, name, 0);
- assertWithMessage("Cannot invoke " + pkg + ":" + name)
- .that(env.execute(Prolog.BUILTIN, "call", head))
- .isTrue();
- }
- private Term removePackage(Term test) {
- Term name = test;
- if (name instanceof StructureTerm && ":".equals(name.name())) {
- name = name.arg(1);
- }
- return name;
- }
- }