diff --git a/source/fab/tools/compiler_wrapper.py b/source/fab/tools/compiler_wrapper.py index e54f98ea..ad76bfad 100644 --- a/source/fab/tools/compiler_wrapper.py +++ b/source/fab/tools/compiler_wrapper.py @@ -47,12 +47,20 @@ def __str__(self): return f"{type(self).__name__}({self._compiler.name})" def get_version(self) -> Tuple[int, ...]: - """ + """Determines the version of the compiler. The implementation in the + compiler wrapper additionally ensures that the wrapper compiler and + compiler wrapper report both the same version. This verifies that the + user's build environment is as expected. For example, this will check + if mpif90 from mpif90-ifort does indeed invoke ifort (and not e.g. + gfortran). + :returns: a tuple of at least 2 integers, representing the version e.g. (6, 10, 1) for version '6.10.1'. :raises RuntimeError: if the compiler was not found, or if it returned an unrecognised output from the version command. + :raises RuntimeError: if the compiler wrapper and wrapped compiler + have different version numbers. """ if self._version is not None: diff --git a/source/fab/tools/versioning.py b/source/fab/tools/versioning.py index 17534c1a..410cc250 100644 --- a/source/fab/tools/versioning.py +++ b/source/fab/tools/versioning.py @@ -3,11 +3,10 @@ # For further details please refer to the file COPYRIGHT # which you should have received as part of this distribution ############################################################################## - -"""This file contains the base class for versioning tools like git and -subversion. It also contains derived classes Git, Subversion, and Fcm. """ - +Versioning tools such as Subversion and Git. +""" +from abc import ABC from pathlib import Path from typing import Dict, List, Optional, Union @@ -15,25 +14,29 @@ from fab.tools.tool import Tool -class Versioning(Tool): - '''This is the base class for versioning tools like git and svn. - - :param name: the name of the tool. - :param exec_name: the name of the executable of this tool. - :param category: the category to which this tool belongs). - ''' - +class Versioning(Tool, ABC): + """ + Base class for versioning tools like Git and Subversion. + """ def __init__(self, name: str, exec_name: Union[str, Path], category: Category): + """ + Constructor. + + :param name: Display name of this tool. + :param exec_name: Executable for this tool. + :param category: Tool belongs to this category. + """ super().__init__(name, exec_name, category, availability_option="help") # ============================================================================= class Git(Versioning): - '''This is the base class for git. - ''' + """ + Interface to Git version control system. + """ def __init__(self): super().__init__("git", "git", @@ -111,20 +114,23 @@ def merge(self, dst: Union[str, Path], # ============================================================================= class Subversion(Versioning): - '''This is the base class for subversion. Note that this is also the - base class for FCM, so it allows overwriting name, exec_name and - category, but will default to use svn. - - :param name: name of the tool, defaults to subversion. - :param exec_name: name of the executable, defaults to "svn". - :param category: the category, FCM or SUBVERSION (the latter is - the default) - ''' - + """ + Interface to the Subversion version control system. + """ def __init__(self, name: Optional[str] = None, exec_name: Optional[Union[str, Path]] = None, category: Category = Category.SUBVERSION): - name = name or "subversion" + """ + Constructor. + + This is class is extended by the FCM interface which is why name and + executable are mutable. + + :param name: Tool name, defaults to "subversion." + :param exec_name: Tool executable, defaults to "svn." + :param category: Tool category, defaults to SUBVERSION. + """ + name = name or "Subversion" exec_name = exec_name or "svn" super().__init__(name, exec_name, category=category) @@ -166,7 +172,9 @@ def export(self, src: Union[str, Path], :param dst: destination path. :param revision: revision to export. ''' - self.execute(['export', '--force'], revision, [str(src), str(dst)]) + self.execute(['export', '--force'], + revision, + [str(src), str(dst)]) def checkout(self, src: Union[str, Path], dst: Union[str, Path], @@ -214,4 +222,4 @@ class Fcm(Subversion): ''' def __init__(self): - super().__init__("fcm", "fcm", Category.FCM) + super().__init__("FCM", "fcm", Category.FCM) diff --git a/tests-old/TestCases/CompiletimeDependency/Makefile b/tests-old/TestCases/CompiletimeDependency/Makefile deleted file mode 100644 index 41b2f272..00000000 --- a/tests-old/TestCases/CompiletimeDependency/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -############################################################################### -# The best way to show how a test case should be built is to build it. -# While we don't have a build system we will use someone elses. -# -# This test builds the same set of source with and without the BEEF macro set. -# -# This will cause the resulting executables to behave differently. -############################################################################### -# The Fortran compiler has to be gfortran as we use the -J argument to redirect -# module file output. -# -export FC = gfortran -export CC ?= gcc - -# By default gmake sets FC to "f77" we need to detect that and force it to our -# default. If it is not set then we still have a default but we allow the user -# to override it. -# -ifeq "x$(shell command -v $(FC))" "x" -$(error Could not find gfortran on PATH) -endif - -all: with-beef without-beef - -with-beef: - $(MAKE) -f with-beef.mk - -without-beef: - $(MAKE) -f without-beef.mk - -clean: - $(MAKE) -f with-beef.mk clean - $(MAKE) -f without-beef.mk clean diff --git a/tests-old/TestCases/CompiletimeDependency/bisto.h b/tests-old/TestCases/CompiletimeDependency/bisto.h deleted file mode 100644 index bcddc2a7..00000000 --- a/tests-old/TestCases/CompiletimeDependency/bisto.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef BISTO_H -#define BISTO_H - -#define LIMIT 5 - -#endif diff --git a/tests-old/TestCases/CompiletimeDependency/hillfort.F90 b/tests-old/TestCases/CompiletimeDependency/hillfort.F90 deleted file mode 100644 index 27907780..00000000 --- a/tests-old/TestCases/CompiletimeDependency/hillfort.F90 +++ /dev/null @@ -1,20 +0,0 @@ -program hillfort - - use iso_fortran_env, only : input_unit, output_unit -#ifdef BEEF - use support_mod, only : characters_in_number -#endif - - implicit none - - integer :: input = 50 - - write(output_unit, '("Input is ", I0)') input - -#ifdef BEEF - write(output_unit, & - '("Number is ", I0, " characters long")') characters_in_number(input) -#endif - write(output_unit, '("Halving the number gives ", I0)') input / 2 - -end program hillfort diff --git a/tests-old/TestCases/CompiletimeDependency/looper.c b/tests-old/TestCases/CompiletimeDependency/looper.c deleted file mode 100644 index 857bac43..00000000 --- a/tests-old/TestCases/CompiletimeDependency/looper.c +++ /dev/null @@ -1,17 +0,0 @@ -#include - -#ifdef BEEF -#include "oxo.h" -#else -#include "bisto.h" -#endif - -int main(int argc, char **argv) { - int counter; - - for (counter=0; counter $@ - -$(DIR)hillfort.expected: | $(DIR) - printf "Input is 50\nNumber is 2 characters long\nHalving the number gives 25\n" > $@ - -test-looper: $(DIR)looper.out $(DIR)looper.expected - diff $^ - -$(DIR)looper.out: $(DIR)looper - ./$< > $@ - -$(DIR)looper.expected: | $(DIR) - printf "Test string\nTest string\nTest string\n" > $@ - -$(DIR)hillfort: $(DIR)support_mod.o $(DIR)hillfort.o - @echo Linking $@ - $(FC) -o $@ $(FFLAGS) $^ - -$(DIR)looper: $(DIR)looper.o - @echo Linking $@ - $(CC) -o $@ $(CFLAGS) $^ - -$(DIR)%.o: %.c | $(DIR) - @echo Compiling $@ - $(CC) -o $@ $(CFLAGS) -c $< - -$(DIR)%.o $(DIR)%.mod: %.f90 | $(DIR) - @echo Compiling $@ - $(FC) -o $(DIR)$*.o $(FFLAGS) -J$(DIR) -c $< - -$(DIR)%.o $(DIR)%.mod: %.F90 | $(DIR) - @echo Compiling $@ - $(FC) -o $(DIR)$*.o $(FFLAGS) -J$(DIR) -c $< - -$(DIR)hillfort.o: hillfort.F90 $(DIR)support_mod.mod -$(DIR)looper.o: looper.c oxo.h -$(DIR)support_mod.o $(DIR)support_mod.mod: support_mod.f90 - -$(DIR): - mkdir -p $@ - -clean: - -rm -r $(DIR) diff --git a/tests-old/TestCases/CompiletimeDependency/without-beef.mk b/tests-old/TestCases/CompiletimeDependency/without-beef.mk deleted file mode 100644 index 09eb3f0b..00000000 --- a/tests-old/TestCases/CompiletimeDependency/without-beef.mk +++ /dev/null @@ -1,55 +0,0 @@ -$(info Building without beef) - -export CFLAGS = -export FFLAGS = - -DIR = nobeef/ - -all: test-hillfort test-looper - -test-hillfort: $(DIR)hillfort.out $(DIR)hillfort.expected - diff $^ - -$(DIR)hillfort.out: $(DIR)hillfort - ./$< > $@ - -$(DIR)hillfort.expected: | $(DIR) - printf "Input is 50\nHalving the number gives 25\n" > $@ - -test-looper: $(DIR)looper.out $(DIR)looper.expected - diff $^ - -$(DIR)looper.out: $(DIR)looper - ./$< > $@ - -$(DIR)looper.expected: | $(DIR) - printf "Test string\nTest string\nTest string\nTest string\nTest string\n" > $@ - -$(DIR)hillfort: $(DIR)hillfort.o - @echo Linking $@ - $(FC) -o $@ $(FFLAGS) $^ - -$(DIR)looper: $(DIR)looper.o - @echo Linking $@ - $(CC) -o $@ $(CFLAGS) $^ - -$(DIR)%.o: %.c | $(DIR) - @echo Compiling $@ - $(CC) -o $@ $(CFLAGS) -c $< - -$(DIR)%.o $(DIR)%.mod: %.f90 | $(DIR) - @echo Compiling $@ - $(FC) -o $(DIR)$*.o $(FFLAGS) -c $< - -$(DIR)%.o $(DIR)%.mod: %.F90 | $(DIR) - @echo Compiling $@ - $(FC) -o $(DIR)$*.o $(FFLAGS) -c $< - -$(DIR)hillfort.o: hillfort.F90 -$(DIR)looper.o: looper.c bisto.h - -$(DIR): - mkdir -p $(DIR) - -clean: - -rm -r $(DIR) diff --git a/tests-old/TestCases/FortranSourceTree/ReadMe b/tests-old/TestCases/FortranSourceTree/ReadMe deleted file mode 100644 index dda01562..00000000 --- a/tests-old/TestCases/FortranSourceTree/ReadMe +++ /dev/null @@ -1,8 +0,0 @@ -Although this directory holds source it is not intended to be compiled. - -Instead it demonstrates the various aspects of a Fortran source tree. It is -intended to exercise corner cases for tools like the database explorer. To -that end there are multiple files containing identically named (but -different) modules. Obviously these cannot be linked as there are ambiguous -symbol names. But the source analysis stage has to be able to deal with -things like this. diff --git a/tests-old/TestCases/FortranSourceTree/fpp_one.f90 b/tests-old/TestCases/FortranSourceTree/fpp_one.f90 deleted file mode 100644 index 574ba1bf..00000000 --- a/tests-old/TestCases/FortranSourceTree/fpp_one.f90 +++ /dev/null @@ -1,23 +0,0 @@ -#if CHOOSE == ONE -module fpp_mod - - use nosuch_mod, only : nonexistant - - implicit none - - public fpp_choice - -contains - - function fpp_choice() - - implicit none - - character(3) :: fpp_choice - - fpp_choice = "ONE" - - end function fpp_choice - -end module fpp_mod -#endif diff --git a/tests-old/TestCases/FortranSourceTree/fpp_two.f90 b/tests-old/TestCases/FortranSourceTree/fpp_two.f90 deleted file mode 100644 index 0b792779..00000000 --- a/tests-old/TestCases/FortranSourceTree/fpp_two.f90 +++ /dev/null @@ -1,23 +0,0 @@ -#if CHOOSE == TWO -module fpp_mod - - implicit none - - public fpp_choice - -contains - - function fpp_choice() - - use unfound_mod, only : not_there - - implicit none - - character(3) :: fpp_choice - - fpp_choice = "TWO" - - end function fpp_choice - -end module fpp_mod -#endif diff --git a/tests-old/TestCases/FortranSourceTree/link1.f90 b/tests-old/TestCases/FortranSourceTree/link1.f90 deleted file mode 100644 index 00c8887e..00000000 --- a/tests-old/TestCases/FortranSourceTree/link1.f90 +++ /dev/null @@ -1,19 +0,0 @@ -module link_mod - - implicit none - - public link_choice - -contains - - function link_choice() - - implicit none - - integer :: link_choice - - link_choice = 1 - - end function link_choice - -end module link_mod diff --git a/tests-old/TestCases/FortranSourceTree/link2.f90 b/tests-old/TestCases/FortranSourceTree/link2.f90 deleted file mode 100644 index b7e86d5f..00000000 --- a/tests-old/TestCases/FortranSourceTree/link2.f90 +++ /dev/null @@ -1,19 +0,0 @@ -module link_mod - - implicit none - - public link_choice - -contains - - function link_choice() - - implicit none - - integer :: link_choice - - link_choice = 2 - - end function link_choice - -end module link_mod diff --git a/tests-old/TestCases/FortranSourceTree/program.F90 b/tests-old/TestCases/FortranSourceTree/program.F90 deleted file mode 100644 index 2e5caafe..00000000 --- a/tests-old/TestCases/FortranSourceTree/program.F90 +++ /dev/null @@ -1,13 +0,0 @@ -program thingumy - - use iso_fortran_env, only : output_unit - use link_mod, only : link_choice - use fpp_mod, only : fpp_choice - - implicit none - - write(output_unit, '("Someone made a decission")') - write(output_unit, '("By linking choice ", I0)') link_choice() - write(output_unit, '("By setting preprocessor variable CHOOSE to ", A)') fpp_choice() - -end program thingumy diff --git a/tests-old/TestCases/FortranSubmodule/Makefile b/tests-old/TestCases/FortranSubmodule/Makefile deleted file mode 100644 index def8a21e..00000000 --- a/tests-old/TestCases/FortranSubmodule/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# The best way to show how a test case should be built is to build it. -# While we don't have a build system we will use someone elses. -# -.SUFFIXES: -.SUFFIXES: .f90 .o .mod - -# By default gmake sets FC to "f77" we need to detect that and force it to our -# default. If it is not set then we still have a default but we allow the user -# to override it. -# -ifeq "$(origin FC)" "default" -export FC = ifort -else -export FC ?= ifort -endif - -OBJECTS = simple_impl.o simple_mod.o class_mod.o class_impl.o test.o - -verify: test.out test.expected - diff $^ - -test.out: test - ./$< >$@ - -test.expected: - printf "Doubler in submodule 14\n\nInitial value 12\nAfter submodule method 29\n" >$@ - -test: $(OBJECTS) - @echo Linking $@ - $(FC) -o $@ $(OBJECTS) - -.f90.o: - @echo Building $@ - $(FC) -o $@ -c $< - -.f90.mod: - @echo Building $@ - $(FC) -o $*.o -c $< - -simple_mod.o simple_mod.mod: simple_mod.f90 -simple_impl.o: simple_impl.f90 simple_mod.mod -class_mod.o class_mod.mod: class_mod.f90 -class_impl.o: class_impl.f90 class_mod.mod -test.o: test.f90 simple_mod.mod class_mod.mod - -clean: - rm *.o *.mod *.smod test test.out test.expected diff --git a/tests-old/TestCases/FortranSubmodule/class_impl.f90 b/tests-old/TestCases/FortranSubmodule/class_impl.f90 deleted file mode 100644 index cd5c2fc6..00000000 --- a/tests-old/TestCases/FortranSubmodule/class_impl.f90 +++ /dev/null @@ -1,28 +0,0 @@ -submodule(class_mod) class_impl - - implicit none - -contains - - module function bar_initialiser( starter ) result(instance) - implicit none - integer, intent(in) :: starter - type(bar_type) :: instance - instance%stuff = starter - end function bar_initialiser - - - module subroutine bar_mangle(this, factor) - implicit none - class(bar_type), intent(inout) :: this - integer, intent(in) :: factor - this%stuff = ieor(this%stuff, factor) - end subroutine bar_mangle - - - module procedure bar_howmuch ! Alternative syntax - implicit none - bar_howmuch = this%stuff - end procedure bar_howmuch - -end submodule class_impl diff --git a/tests-old/TestCases/FortranSubmodule/class_mod.f90 b/tests-old/TestCases/FortranSubmodule/class_mod.f90 deleted file mode 100644 index 25d6616c..00000000 --- a/tests-old/TestCases/FortranSubmodule/class_mod.f90 +++ /dev/null @@ -1,59 +0,0 @@ -module class_mod - - implicit none - - type, abstract :: foo_type - private - integer :: stuff - contains - private - procedure(mangle_if), public, deferred :: mangle - procedure(how_much_if), public, deferred :: how_much - end type foo_type - - interface - subroutine mangle_if(this, factor) - import foo_type - implicit none - class(foo_type), intent(inout) :: this - integer, intent(in) :: factor - end subroutine mangle_if - function how_much_if(this) - import foo_type - implicit none - class(foo_type), intent(inout) :: this - integer :: how_much_if - end function how_much_if - end interface - - type, extends(foo_type) :: bar_type - private - contains - private - procedure, public :: mangle => bar_mangle - procedure, public :: how_much => bar_howmuch - end type bar_type - - interface bar_type - procedure bar_initialiser - end interface bar_type - - interface - module function bar_initialiser(starter) result(instance) - implicit none - integer,intent(in) :: starter - type(bar_type) :: instance - end function bar_initialiser - module subroutine bar_mangle(this, factor) - implicit none - class(bar_type), intent(inout) :: this - integer, intent(in) :: factor - end subroutine bar_mangle - module function bar_howmuch(this) - implicit none - class(bar_type), intent(inout) :: this - integer :: bar_howmuch - end function bar_howmuch - end interface - -end module class_mod diff --git a/tests-old/TestCases/FortranSubmodule/simple_impl.f90 b/tests-old/TestCases/FortranSubmodule/simple_impl.f90 deleted file mode 100644 index 74b63601..00000000 --- a/tests-old/TestCases/FortranSubmodule/simple_impl.f90 +++ /dev/null @@ -1,18 +0,0 @@ -submodule(simple_mod) simple_impl - - implicit none - -contains - - module function returnerer(thing) - - implicit none - - integer, intent(in) :: thing - integer :: returnerer - - returnerer = 2 * thing - - end function returnerer - -end submodule simple_impl diff --git a/tests-old/TestCases/FortranSubmodule/simple_mod.f90 b/tests-old/TestCases/FortranSubmodule/simple_mod.f90 deleted file mode 100644 index 8bd6b4d9..00000000 --- a/tests-old/TestCases/FortranSubmodule/simple_mod.f90 +++ /dev/null @@ -1,13 +0,0 @@ -module simple_mod - - implicit none - - interface - module function returnerer(thing) - implicit none - integer, intent(in) :: thing - integer :: returnerer - end function returnerer - end interface - -end module simple_mod diff --git a/tests-old/TestCases/FortranSubmodule/test.f90 b/tests-old/TestCases/FortranSubmodule/test.f90 deleted file mode 100644 index 3ac9f4c2..00000000 --- a/tests-old/TestCases/FortranSubmodule/test.f90 +++ /dev/null @@ -1,22 +0,0 @@ -program test - - use iso_fortran_env, only : output_unit - - use class_mod, only : bar_type - use simple_mod, only : returnerer - - implicit none - - type(bar_type) :: thing - - thing = bar_type(12) - - write(output_unit, '("Doubler in submodule ", I0)') returnerer(7) - write(output_unit, '()') - - write(output_unit, '("Initial value ", I0)') thing%how_much() - call thing%mangle(17) - write(output_unit, & - '("After submodule method ", I0)') thing%how_much() - -end program test diff --git a/tests-old/TestCases/Makefile b/tests-old/TestCases/Makefile deleted file mode 100644 index 506623c4..00000000 --- a/tests-old/TestCases/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -THIS_DIR := $(dir $(lastword $(MAKEFILE_LIST))) - -TEST_DIRS := $(shell find $(THIS_DIR) -type d -mindepth 1 -maxdepth 1 -print) - -run: $(addprefix run/, $(TEST_DIRS)) - -run/%: - $(MAKE) -C $* - -clean: $(addprefix clean/, $(TEST_DIRS)) - -clean/%: - $(MAKE) -C $* clean diff --git a/tests-old/TestCases/MinimalC/Makefile b/tests-old/TestCases/MinimalC/Makefile deleted file mode 100644 index 95242a70..00000000 --- a/tests-old/TestCases/MinimalC/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -# The best way to show how a test case should be built is to build it. -# While we don't have a build system we will use someone elses. -# -.SUFFIXES: -.SUFFIXES: .c .o - -# By default gmake sets FC to "cc" we need to detect that and force it to our -# default. If it is not set then we still have a default but we allow the user -# to override it. -# -ifeq "$(origin CC)" "default" -export CC = gcc -else -export CC ?= gcc -endif - -OBJECTS = program.o - -verify: test.out test.expected - diff $^ - -test.out: test - ./$< >$@ - -test.expected: - printf "Hello world!\n" >$@ - -test: $(OBJECTS) - @echo Linking $@ - $(CC) -o $@ $(OBJECTS) - -.c.o: - @echo Compiling $@ - $(CC) -o $@ -c $< - -program.o: program.c - -clean: - rm *.o test test.out test.expected diff --git a/tests-old/TestCases/MinimalC/program.c b/tests-old/TestCases/MinimalC/program.c deleted file mode 100644 index ccec439e..00000000 --- a/tests-old/TestCases/MinimalC/program.c +++ /dev/null @@ -1,11 +0,0 @@ -/***************************************************************************** - * It's that simple example program again. - *****************************************************************************/ - -#include - -int main(int argc, char **argv) -{ - printf("Hello world!\n"); - return 0; -} diff --git a/tests-old/TestCases/PSyclone/Makefile b/tests-old/TestCases/PSyclone/Makefile deleted file mode 100644 index ca4e7069..00000000 --- a/tests-old/TestCases/PSyclone/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -# The best way to show how a test case should be built is to build it. -# While we don't have a build system we will use someone elses. -# -# This test assumes that the PSyclone code generation tool is available on the -# executino path. i.e. That the directory containing it appears in the PATH -# environment variable. -# -.SUFFIXES: -.SUFFIXES: .x90 .f90 .F90 .o .mod - -# The compiler has to be ifort as we use the "-module" argument to redirect -# module file storage. -# -export FC = ifort - -PSYCLONE = psyclone - -ifeq "x$(shell command -v $(PSYCLONE))" "x" -$(error Could not find the PSyclone script on PATH) -endif - -DIRECTORIES = kernels model - -objects: kernels/my_kernel_mod.o algorithm_mod.o algorithm_mod_psy.o - -%.o %.mod: %.f90 - @echo Compiling $< - $(FC) -o $*.o -module $(dir $@) $(addprefix -I,$(DIRECTORIES)) -c $< - -%_psy.f90 %.f90: %.x90 optimisation.py - @echo Psyclone $< - $(PSYCLONE) -oalg $*.f90 -opsy $*_psy.f90 -d kernels \ - -s $(realpath optimisation.py) \ - -api dynamo0.3 -l -nodm $< - -algorithm_mod.f90 \ -algorithm_mod_psy.f90: algorithm_mod.x90 \ - kernels/my_kernel_mod.f90 optimisation.py -algorithm_mod.o \ -algorithm_mod.mod: algorithm_mod.f90 algorithm_mod_psy.mod \ - model/field_mod.mod kernels/my_kernel_mod.mod -algorithm_mod_psy.o \ -algorithm_mod_psy.mod: algorithm_mod_psy.f90 \ - model/field_mod.mod model/operator_mod.mod \ - kernels/my_kernel_mod.mod -kernels/my_kernel_mod.o \ -kernels/my_kernel_mod.mod: kernels/my_kernel_mod.f90 \ - model/argument_mod.mod model/constants_mod.mod \ - model/functionspace_mod.mod model/kernel_mod.mod \ - -model/field_mod.o \ -model/field_mod.mod: model/field_mod.f90 model/functionspace_mod.mod - -clean: - -rm -r *.o *.mod kernels/*.o kernels/*.mod model/*.o model/*.mod - -rm *.pyc algorithm_mod.f90 algorithm_mod_psy.f90 diff --git a/tests-old/TestCases/PSyclone/algorithm_mod.x90 b/tests-old/TestCases/PSyclone/algorithm_mod.x90 deleted file mode 100644 index cfac16bb..00000000 --- a/tests-old/TestCases/PSyclone/algorithm_mod.x90 +++ /dev/null @@ -1,21 +0,0 @@ -module algorithm_mod - - use field_mod, only : field_type - use my_kernel_mod, only : my_kernel_type - - implicit none - -contains - - subroutine algorithm() - - implicit none - - type(field_type) :: field - - field = field_type() - call invoke( name='a_test', my_kernel_type( field ) ) - - end subroutine algorithm - -end module algorithm_mod diff --git a/tests-old/TestCases/PSyclone/kernels/my_kernel_mod.f90 b/tests-old/TestCases/PSyclone/kernels/my_kernel_mod.f90 deleted file mode 100644 index 035de698..00000000 --- a/tests-old/TestCases/PSyclone/kernels/my_kernel_mod.f90 +++ /dev/null @@ -1,49 +0,0 @@ -module my_kernel_mod - - use argument_mod, only : arg_type, cells, gh_field, gh_write - use functionspace_mod, only : w3 - use kernel_mod, only : kernel_type - - implicit none - - private - - type, public, extends(kernel_type) :: my_kernel_type - private - type(arg_type) :: meta_args(1) = (/ & - arg_type( gh_field, gh_write, w3 ) & - /) - integer :: iterates_over = cells - contains - procedure, nopass :: my_kernel_code - end type - - public :: my_kernel_code - -contains - - subroutine my_kernel_code( nlayers, field_1_w3, ndf_w3, undf_w3, map_w3 ) - - use constants_mod, only : r_def - - implicit none - - integer, intent(in) :: nlayers - integer, intent(in) :: ndf_w3 - integer, intent(in) :: undf_w3 - real(kind=r_def), intent(out) :: field_1_w3(undf_w3) - integer, intent(in) :: map_w3(ndf_w3) - - integer :: d, k - real :: v(ndf_w3) - - call random_number(v) - do k=0, nlayers - do d=0, ndf_w3 - field_1_w3(map_w3(d)) = v(d) + k - end do - end do - - end subroutine my_kernel_code - -end module my_kernel_mod diff --git a/tests-old/TestCases/PSyclone/model/argument_mod.f90 b/tests-old/TestCases/PSyclone/model/argument_mod.f90 deleted file mode 100644 index 2cf7638c..00000000 --- a/tests-old/TestCases/PSyclone/model/argument_mod.f90 +++ /dev/null @@ -1,21 +0,0 @@ -module argument_mod - - implicit none - - private - - integer, public, parameter :: gh_field = 507 - integer, public, parameter :: gh_write = 65 - integer, public, parameter :: cells = 396 - - type, public :: arg_type - integer :: arg_type - integer :: arg_intent - integer :: wspace = -1 - integer :: from_wspace = -1 - integer :: stencil_map = -1 - integer :: mesh_arg = -1 - end type arg_type - -end module argument_mod - diff --git a/tests-old/TestCases/PSyclone/model/constants_mod.f90 b/tests-old/TestCases/PSyclone/model/constants_mod.f90 deleted file mode 100644 index bc5170e2..00000000 --- a/tests-old/TestCases/PSyclone/model/constants_mod.f90 +++ /dev/null @@ -1,11 +0,0 @@ -module constants_mod - - use iso_fortran_env, only : real64 - - implicit none - - private - - integer, public, parameter :: r_def = real64 - -end module constants_mod diff --git a/tests-old/TestCases/PSyclone/model/field_mod.f90 b/tests-old/TestCases/PSyclone/model/field_mod.f90 deleted file mode 100644 index 5fb9b872..00000000 --- a/tests-old/TestCases/PSyclone/model/field_mod.f90 +++ /dev/null @@ -1,32 +0,0 @@ -module field_mod - - use constants_mod, only : r_def - use functionspace_mod, only : functionspace_type - - implicit none - - private - - type, public :: field_type - private - contains - private - procedure, public :: get_proxy - end type field_type - - type, public :: field_proxy_type - private - real(r_def), public :: data(10) - type(functionspace_type), public :: vspace - end type field_proxy_type - -contains - - function get_proxy(this) - implicit none - class(field_type), intent(inout) :: this - type(field_proxy_type) :: get_proxy - get_proxy%vspace = functionspace_type() - end function get_proxy - -end module field_mod diff --git a/tests-old/TestCases/PSyclone/model/functionspace_mod.f90 b/tests-old/TestCases/PSyclone/model/functionspace_mod.f90 deleted file mode 100644 index 56c9b016..00000000 --- a/tests-old/TestCases/PSyclone/model/functionspace_mod.f90 +++ /dev/null @@ -1,78 +0,0 @@ -module functionspace_mod - - implicit none - - private - - integer, public, parameter :: W0 = 173 - integer, public, parameter :: W1 = 194 - integer, public, parameter :: W2 = 889 - integer, public, parameter :: W2V = 857 - integer, public, parameter :: W2H = 884 - integer, public, parameter :: W2broken = 211 - integer, public, parameter :: W2trace = 213 - integer, public, parameter :: W3 = 424 - integer, public, parameter :: Wtheta = 274 - integer, public, parameter :: Wchi = 869 - - type, public :: functionspace_type - private - integer, pointer :: dofmap(:, :) - contains - private - procedure, public :: get_ncell - procedure, public :: get_ndf - procedure, public :: get_nlayers - procedure, public :: get_undf - procedure, public :: get_whole_dofmap - ! There should be a finaliser but for testing it's too much work. - end type functionspace_type - - interface functionspace_type - procedure functionspace_initialise - end interface - -contains - - function functionspace_initialise() result(instance) - implicit none - type(functionspace_type) :: instance - allocate( instance%dofmap(2, 1) ) - end function functionspace_initialise - - function get_ncell(this) - implicit none - class(functionspace_type), intent(inout) :: this - integer :: get_ncell - get_ncell = 1 - end function get_ncell - - function get_ndf(this) - implicit none - class(functionspace_type), intent(inout) :: this - integer :: get_ndf - get_ndf = 1 - end function get_ndf - - function get_undf(this) - implicit none - class(functionspace_type), intent(inout) :: this - integer :: get_undf - get_undf = 1 - end function get_undf - - function get_nlayers(this) - implicit none - class(functionspace_type), intent(inout) :: this - integer :: get_nlayers - get_nlayers = 1 - end function get_nlayers - - function get_whole_dofmap(this) - implicit none - class(functionspace_type), intent(inout) :: this - integer, pointer :: get_whole_dofmap(:, :) - get_whole_dofmap => this%dofmap - end function get_whole_dofmap - -end module functionspace_mod diff --git a/tests-old/TestCases/PSyclone/model/kernel_mod.f90 b/tests-old/TestCases/PSyclone/model/kernel_mod.f90 deleted file mode 100644 index 821c1ec3..00000000 --- a/tests-old/TestCases/PSyclone/model/kernel_mod.f90 +++ /dev/null @@ -1,11 +0,0 @@ -module kernel_mod - - implicit none - - private - - type, public, abstract :: kernel_type - private - end type - -end module kernel_mod diff --git a/tests-old/TestCases/PSyclone/model/operator_mod.f90 b/tests-old/TestCases/PSyclone/model/operator_mod.f90 deleted file mode 100644 index a06a63ca..00000000 --- a/tests-old/TestCases/PSyclone/model/operator_mod.f90 +++ /dev/null @@ -1,23 +0,0 @@ -module operator_mod - - implicit none - - private - - type, public :: operator_type - private - end type operator_type - - type, public :: operator_proxy_type - private - end type operator_proxy_type - - type, public :: columnwise_operator_type - private - end type columnwise_operator_type - - type, public :: columnwise_operator_proxy_type - private - end type columnwise_operator_proxy_type - -end module operator_mod diff --git a/tests-old/TestCases/PSyclone/optimisation.py b/tests-old/TestCases/PSyclone/optimisation.py deleted file mode 100644 index d995e883..00000000 --- a/tests-old/TestCases/PSyclone/optimisation.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python -''' -PSyclone transformation script for the Dynamo0p3 API to apply -colouring and OpenMP. -''' -from __future__ import absolute_import, print_function - -from psyclone.transformations import Dynamo0p3ColourTrans, \ - Dynamo0p3OMPLoopTrans, \ - OMPParallelTrans -from psyclone.dynamo0p3 import DISCONTINUOUS_FUNCTION_SPACES - - -def trans(psy): - ''' - Applies PSyclone colouring and OpenMP transformations. - ''' - ctrans = Dynamo0p3ColourTrans() - otrans = Dynamo0p3OMPLoopTrans() - oregtrans = OMPParallelTrans() - - # Loop over all of the Invokes in the PSy object - for invoke in psy.invokes.invoke_list: - - print("Transforming invoke '{0}' ...".format(invoke.name)) - schedule = invoke.schedule - - # Colour loops over cells unless they are on discontinuous - # spaces (W3, WTHETA and W2V) or over dofs - for loop in schedule.loops(): - if loop.iteration_space == "cells" \ - and loop.field_space.orig_name \ - not in DISCONTINUOUS_FUNCTION_SPACES: - schedule, _ = ctrans.apply(loop) - - # Add OpenMP to loops over colours. - for loop in schedule.loops(): - if loop.loop_type != "colours": - schedule, _ = oregtrans.apply(loop) - schedule, _ = otrans.apply(loop, reprod=True) - - schedule.view() - - return psy diff --git a/tests-old/TestCases/SimpleLFRic/Makefile b/tests-old/TestCases/SimpleLFRic/Makefile deleted file mode 100644 index 78fa0630..00000000 --- a/tests-old/TestCases/SimpleLFRic/Makefile +++ /dev/null @@ -1,143 +0,0 @@ -# The best way to show how a test case should be built is to build it. -# While we don't have a build system we will use someone elses. -# -# This test expects the MPICH compiler wrapper scripts to be available on -# PATH. Furthermore it expects them to be wrapping Intel Fortran. -# -# It also expects the PSyclone source generator and pFUnit processor to be -# available on PATH. -# -# As recommended by the pFUnit developers it exptects a macro PFUNIT to -# contain the full path to the pFUnit install directory. -# -.SUFFIXES: -.SUFFIXES: .pf .f90 .F90 .o .mod - -APP_OBJECTS = util.o util_mod.o \ - algorithm_mod.o algorithm_mod_psy.o \ - model/field_mod.o model/functionspace_mod.o model/mesh_mod.o \ - model/kernel_mod.o kernels/my_kernel_mod.o \ - thing.o -TEST_OBJECTS = kernels/my_kernel_mod.o my_kernel_test_mod.o driver.o - -FC = mpif90 -FFLAGS = -Ikernels -Imodel -I$(PFUNIT)/mod -debug full -traceback -CC = gcc -CFLAGS = -std=c99 -g -LFLAGS = -qopenmp -debug full -traceback -PSYCLONE = psyclone -PFPROC = pFUnitParser.py - -# We use the "-module" argument to redirect module file creation so the -# compiler wrapped by MPI must be ifort. -# -ifneq "$(firstword $(shell $(FC) -show))" "ifort" -$(error Please build with MPICH for Intel Fortran) -endif - -ifeq "x$(shell command -v $(PSYCLONE))" "x" -$(error Could not find the PSyclone script on PATH) -endif - -ifeq "x$(shell command -v $(PFPROC))" "x" -$(error Could not find the pFUnit processor on PATH) -endif - -verify: test-thing test-test - -test-thing: thing.out thing.expected - diff $^ - -thing.out: thing - ./$< >$@ - -thing.expected: - printf "Some hash: 7\n" >$@ - for iter in 1 2 3 4 5 6 7 8 9 10; do printf "Field data: 1.0000\n"; done >>$@ - -test-test: test.out test.expected - diff $^ - -test.out: test - ./$< | tail -n 2 >$@ - -test.expected: - printf " OK\n (1 test)\n" >$@ - -thing: $(APP_OBJECTS) - @echo Linking $@ - $(FC) -o $@ -g $(APP_OBJECTS) -lstdc++ - -test: $(TEST_OBJECTS) - @echo Linking $@ - $(FC) $(LFLAGS) -o $@ -L$(PFUNIT)/lib $(TEST_OBJECTS) -l pfunit - -%.o: %.c - @echo Compiling $@ - $(CC) -o $@ $(CFLAGS) -c $< - -%.o %.mod: %.f90 - @echo Compiling $@ - $(FC) -o $*.o $(FFLAGS) -module $(dir $@) -c $< - -%.o %.mod: %.F90 - @echo Compiling $@ - $(FC) -o $*.o $(FFLAGS) -module $(dir $@) -c $< - -%.f90 %_psy.F90: %.x90 optimisation.py - @echo Generating $@ - $(PSYCLONE) -oalg $*.f90 -opsy $*_psy.F90 -d kernels \ - -s $(realpath optimisation.py) -api dynamo0.3 -l -dm $< - -util_mod.f90: util_mod.template # Really should be util.c - @echo Generating $@ - # This cat is in lue of a generator - cat util_mod.template > $@ - -.pf.F90: - @echo Generating $@ - $(PFPROC) $< $@ - -driver.o: $(PFUNIT)/include/driver.F90 testSuites.inc - @echo Compiling $@ - $(FC) -o $@ -I$(PFUNIT)/mod -c $< - -testSuites.inc: - @echo Creating $@ - echo ADD_TEST_SUITE\(my_kernel_test_mod_suite\) > $@ - -my_kernel_test_mod.o \ -my_kernel_test_mod.mod: my_kernel_test_mod.F90 \ - kernels/my_kernel_mod.mod model/constants_mod.mod -kernel_test_mod.F90: kernel_test_mod.pf - -algorithm_mod.o \ -algorithm_mod.mod: algorithm_mod.f90 algorithm_mod_psy.mod \ - model/field_mod.mod kernels/my_kernel_mod.mod -algorithm_mod.f90: algorithm_mod.x90 kernels/my_kernel_mod.f90 optimisation.py -algorithm_mod_psy.o \ -algorithm_mod_psy.mod: algorithm_mod_psy.F90 \ - model/field_mod.mod model/operator_mod.mod \ - kernels/my_kernel_mod.mod -algorithm_mod_psy.F90: algorithm_mod.x90 \ - kernels/my_kernel_mod.f90 optimisation.py -kernels/my_kernel_mod.o \ -kernels/my_kernel_mod.mod: kernels/my_kernel_mod.f90 model/mesh_mod.mod\ - model/argument_mod.mod model/constants_mod.mod \ - model/functionspace_mod.mod model/kernel_mod.mod - -model/field_mod.o: model/field_mod.f90 \ - model/constants_mod.mod model/functionspace_mod.mod \ - model/mesh_mod.mod - -util_mod.o: util_mod.f90 model/constants_mod.mod - -thing.o: thing.f90 algorithm_mod.mod algorithm_mod_psy.mod util_mod.mod \ - model/field_mod.mod - -clean: - -rm *.o *.mod *.pyc kernels/*.o kernels/*.mod model/*.o model/*.mod - -rm testSuites.inc - -rm algorithm_mod.f90 algorithm_mod_psy.F90 my_kernel_test_mod.F90 - -rm util_mod.f90 - -rm test test.out test.expected thing thing.out thing.expected diff --git a/tests-old/TestCases/SimpleLFRic/algorithm_mod.x90 b/tests-old/TestCases/SimpleLFRic/algorithm_mod.x90 deleted file mode 100644 index d37dbf98..00000000 --- a/tests-old/TestCases/SimpleLFRic/algorithm_mod.x90 +++ /dev/null @@ -1,24 +0,0 @@ -module algorithm_mod - - use field_mod, only : field_type - use my_kernel_mod, only : my_kernel_type - use util_mod, only : hash - - implicit none - - private - public :: algorithm - -contains - - subroutine algorithm(field) - - implicit none - - class(field_type), intent(inout) :: field - - call invoke( my_kernel_type(field) ) - - end subroutine algorithm - -end module algorithm_mod diff --git a/tests-old/TestCases/SimpleLFRic/kernels/my_kernel_mod.f90 b/tests-old/TestCases/SimpleLFRic/kernels/my_kernel_mod.f90 deleted file mode 100644 index d6e3dfc2..00000000 --- a/tests-old/TestCases/SimpleLFRic/kernels/my_kernel_mod.f90 +++ /dev/null @@ -1,47 +0,0 @@ -module my_kernel_mod - - use argument_mod, only : arg_type, cells, gh_field, gh_write - use functionspace_mod, only : w3 - use kernel_mod, only : kernel_type - - implicit none - - private - - type, public, extends(kernel_type) :: my_kernel_type - private - type(arg_type) :: meta_args(1) = (/ & - arg_type( gh_field, gh_write, w3 ) & - /) - integer :: iterates_over = cells - contains - procedure, nopass :: my_kernel_code - end type - - public :: my_kernel_code - -contains - - subroutine my_kernel_code( nlayers, field_1_w3, ndf_w3, undf_w3, map_w3 ) - - use constants_mod, only : r_def - - implicit none - - integer, intent(in) :: nlayers - integer, intent(in) :: ndf_w3 - integer, intent(in) :: undf_w3 - real(kind=r_def), intent(out) :: field_1_w3(undf_w3) - integer, intent(in) :: map_w3(ndf_w3) - - integer :: d, k - - do k=0, nlayers - do d=0, ndf_w3 - field_1_w3(map_w3(d)) = d + k - end do - end do - - end subroutine my_kernel_code - -end module my_kernel_mod diff --git a/tests-old/TestCases/SimpleLFRic/model/argument_mod.f90 b/tests-old/TestCases/SimpleLFRic/model/argument_mod.f90 deleted file mode 100644 index 2cf7638c..00000000 --- a/tests-old/TestCases/SimpleLFRic/model/argument_mod.f90 +++ /dev/null @@ -1,21 +0,0 @@ -module argument_mod - - implicit none - - private - - integer, public, parameter :: gh_field = 507 - integer, public, parameter :: gh_write = 65 - integer, public, parameter :: cells = 396 - - type, public :: arg_type - integer :: arg_type - integer :: arg_intent - integer :: wspace = -1 - integer :: from_wspace = -1 - integer :: stencil_map = -1 - integer :: mesh_arg = -1 - end type arg_type - -end module argument_mod - diff --git a/tests-old/TestCases/SimpleLFRic/model/constants_mod.f90 b/tests-old/TestCases/SimpleLFRic/model/constants_mod.f90 deleted file mode 100644 index bc5170e2..00000000 --- a/tests-old/TestCases/SimpleLFRic/model/constants_mod.f90 +++ /dev/null @@ -1,11 +0,0 @@ -module constants_mod - - use iso_fortran_env, only : real64 - - implicit none - - private - - integer, public, parameter :: r_def = real64 - -end module constants_mod diff --git a/tests-old/TestCases/SimpleLFRic/model/field_mod.f90 b/tests-old/TestCases/SimpleLFRic/model/field_mod.f90 deleted file mode 100644 index 9675d36c..00000000 --- a/tests-old/TestCases/SimpleLFRic/model/field_mod.f90 +++ /dev/null @@ -1,59 +0,0 @@ -module field_mod - - use constants_mod, only : r_def - use functionspace_mod, only : functionspace_type - use mesh_mod, only : mesh_type - - implicit none - - private - - type, public :: field_type - private - type(mesh_type), pointer :: mesh - contains - private - procedure, public :: get_mesh - procedure, public :: get_proxy - ! There should be a finalising but I can't be bothered - end type field_type - - interface field_type - procedure :: field_initialiser - end interface field_type - - type, public :: field_proxy_type - private - real(r_def), public :: data(10) - type(functionspace_type), public :: vspace - contains - procedure set_dirty - end type field_proxy_type - -contains - - function field_initialiser() result(instance) - implicit none - type(field_type) :: instance - allocate( instance%mesh ) - end function field_initialiser - - function get_mesh(this) - implicit none - class(field_type), intent(inout) :: this - type(mesh_type), pointer :: get_mesh - get_mesh => this%mesh - end function get_mesh - - function get_proxy(this) - implicit none - class(field_type), intent(inout) :: this - type(field_proxy_type) :: get_proxy - get_proxy%vspace = functionspace_type() - end function get_proxy - - subroutine set_dirty(this) - implicit none - class(field_Proxy_type), intent(inout) :: this - end subroutine set_dirty -end module field_mod diff --git a/tests-old/TestCases/SimpleLFRic/model/functionspace_mod.f90 b/tests-old/TestCases/SimpleLFRic/model/functionspace_mod.f90 deleted file mode 100644 index 56c9b016..00000000 --- a/tests-old/TestCases/SimpleLFRic/model/functionspace_mod.f90 +++ /dev/null @@ -1,78 +0,0 @@ -module functionspace_mod - - implicit none - - private - - integer, public, parameter :: W0 = 173 - integer, public, parameter :: W1 = 194 - integer, public, parameter :: W2 = 889 - integer, public, parameter :: W2V = 857 - integer, public, parameter :: W2H = 884 - integer, public, parameter :: W2broken = 211 - integer, public, parameter :: W2trace = 213 - integer, public, parameter :: W3 = 424 - integer, public, parameter :: Wtheta = 274 - integer, public, parameter :: Wchi = 869 - - type, public :: functionspace_type - private - integer, pointer :: dofmap(:, :) - contains - private - procedure, public :: get_ncell - procedure, public :: get_ndf - procedure, public :: get_nlayers - procedure, public :: get_undf - procedure, public :: get_whole_dofmap - ! There should be a finaliser but for testing it's too much work. - end type functionspace_type - - interface functionspace_type - procedure functionspace_initialise - end interface - -contains - - function functionspace_initialise() result(instance) - implicit none - type(functionspace_type) :: instance - allocate( instance%dofmap(2, 1) ) - end function functionspace_initialise - - function get_ncell(this) - implicit none - class(functionspace_type), intent(inout) :: this - integer :: get_ncell - get_ncell = 1 - end function get_ncell - - function get_ndf(this) - implicit none - class(functionspace_type), intent(inout) :: this - integer :: get_ndf - get_ndf = 1 - end function get_ndf - - function get_undf(this) - implicit none - class(functionspace_type), intent(inout) :: this - integer :: get_undf - get_undf = 1 - end function get_undf - - function get_nlayers(this) - implicit none - class(functionspace_type), intent(inout) :: this - integer :: get_nlayers - get_nlayers = 1 - end function get_nlayers - - function get_whole_dofmap(this) - implicit none - class(functionspace_type), intent(inout) :: this - integer, pointer :: get_whole_dofmap(:, :) - get_whole_dofmap => this%dofmap - end function get_whole_dofmap - -end module functionspace_mod diff --git a/tests-old/TestCases/SimpleLFRic/model/kernel_mod.f90 b/tests-old/TestCases/SimpleLFRic/model/kernel_mod.f90 deleted file mode 100644 index 821c1ec3..00000000 --- a/tests-old/TestCases/SimpleLFRic/model/kernel_mod.f90 +++ /dev/null @@ -1,11 +0,0 @@ -module kernel_mod - - implicit none - - private - - type, public, abstract :: kernel_type - private - end type - -end module kernel_mod diff --git a/tests-old/TestCases/SimpleLFRic/model/mesh_mod.f90 b/tests-old/TestCases/SimpleLFRic/model/mesh_mod.f90 deleted file mode 100644 index 3e8ccd91..00000000 --- a/tests-old/TestCases/SimpleLFRic/model/mesh_mod.f90 +++ /dev/null @@ -1,22 +0,0 @@ -module mesh_mod - - implicit none - - private - - type, public :: mesh_type - private - contains - procedure get_last_edge_cell - end type mesh_type - -contains - - function get_last_edge_cell(this) - implicit none - class(mesh_type), intent(inout) :: this - integer :: get_last_edge_cell - get_last_edge_cell = 1 - end function get_last_edge_cell - -end module mesh_mod diff --git a/tests-old/TestCases/SimpleLFRic/model/operator_mod.f90 b/tests-old/TestCases/SimpleLFRic/model/operator_mod.f90 deleted file mode 100644 index a06a63ca..00000000 --- a/tests-old/TestCases/SimpleLFRic/model/operator_mod.f90 +++ /dev/null @@ -1,23 +0,0 @@ -module operator_mod - - implicit none - - private - - type, public :: operator_type - private - end type operator_type - - type, public :: operator_proxy_type - private - end type operator_proxy_type - - type, public :: columnwise_operator_type - private - end type columnwise_operator_type - - type, public :: columnwise_operator_proxy_type - private - end type columnwise_operator_proxy_type - -end module operator_mod diff --git a/tests-old/TestCases/SimpleLFRic/my_kernel_test_mod.pf b/tests-old/TestCases/SimpleLFRic/my_kernel_test_mod.pf deleted file mode 100644 index 832926b1..00000000 --- a/tests-old/TestCases/SimpleLFRic/my_kernel_test_mod.pf +++ /dev/null @@ -1,27 +0,0 @@ -module my_kernel_test_mod - - use pFUnit_mod - use constants_mod, only : r_def - use my_kernel_mod, only : my_kernel_code - - implicit none - -contains - - @test - subroutine test_my_kernel - - implicit none - - real(r_def) :: dblock(27) - real(r_def) :: expected(27) = (/4,5,6,7,8,9,10,11,12, & - 0,0,0,0,0,0,0,0,0, & - 0,0,0,0,0,0,0,0,0/) - integer :: dofs(9) = (/1,2,3,4,5,6,7,8,9/) - - call my_kernel_code( 3, dblock, 9, 27, dofs) - @assertEqual(expected, dblock) - - end subroutine test_my_kernel - -end module my_kernel_test_mod diff --git a/tests-old/TestCases/SimpleLFRic/optimisation.py b/tests-old/TestCases/SimpleLFRic/optimisation.py deleted file mode 100644 index d995e883..00000000 --- a/tests-old/TestCases/SimpleLFRic/optimisation.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python -''' -PSyclone transformation script for the Dynamo0p3 API to apply -colouring and OpenMP. -''' -from __future__ import absolute_import, print_function - -from psyclone.transformations import Dynamo0p3ColourTrans, \ - Dynamo0p3OMPLoopTrans, \ - OMPParallelTrans -from psyclone.dynamo0p3 import DISCONTINUOUS_FUNCTION_SPACES - - -def trans(psy): - ''' - Applies PSyclone colouring and OpenMP transformations. - ''' - ctrans = Dynamo0p3ColourTrans() - otrans = Dynamo0p3OMPLoopTrans() - oregtrans = OMPParallelTrans() - - # Loop over all of the Invokes in the PSy object - for invoke in psy.invokes.invoke_list: - - print("Transforming invoke '{0}' ...".format(invoke.name)) - schedule = invoke.schedule - - # Colour loops over cells unless they are on discontinuous - # spaces (W3, WTHETA and W2V) or over dofs - for loop in schedule.loops(): - if loop.iteration_space == "cells" \ - and loop.field_space.orig_name \ - not in DISCONTINUOUS_FUNCTION_SPACES: - schedule, _ = ctrans.apply(loop) - - # Add OpenMP to loops over colours. - for loop in schedule.loops(): - if loop.loop_type != "colours": - schedule, _ = oregtrans.apply(loop) - schedule, _ = otrans.apply(loop, reprod=True) - - schedule.view() - - return psy diff --git a/tests-old/TestCases/SimpleLFRic/thing.f90 b/tests-old/TestCases/SimpleLFRic/thing.f90 deleted file mode 100644 index b5dd42a0..00000000 --- a/tests-old/TestCases/SimpleLFRic/thing.f90 +++ /dev/null @@ -1,27 +0,0 @@ -program thing - - use iso_fortran_env, only : output_unit - - use algorithm_mod, only : algorithm - use field_mod, only : field_type, field_proxy_type - use util_mod, only : hash - - implicit none - - type(field_type) :: field - - real, target :: something(4) - real, pointer :: some_pointer(:) => null() - - type(field_proxy_type) :: accessor - - call random_number(something) - some_pointer => something - write(output_unit, '("Some hash: ", I0)') hash(some_pointer) - - accessor = field%get_proxy() - accessor%data = 1.0 - call algorithm(field) - write(output_unit, '("Field data: ", F17.4)') accessor%data - -end program thing diff --git a/tests-old/TestCases/SimpleLFRic/util.c b/tests-old/TestCases/SimpleLFRic/util.c deleted file mode 100644 index 9deefc1b..00000000 --- a/tests-old/TestCases/SimpleLFRic/util.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "util.h" - -int8_t eor_hash(void *block, int length) { - int8_t hash = 0xff; - for (unsigned int index = 0; index < length; ++index) { - hash = hash ^ ((int8_t *)block)[index]; - } - return hash; -} diff --git a/tests-old/TestCases/SimpleLFRic/util.h b/tests-old/TestCases/SimpleLFRic/util.h deleted file mode 100644 index c254a41d..00000000 --- a/tests-old/TestCases/SimpleLFRic/util.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef UTIL_H -#define UTIL_H - -#include - -extern int8_t eor_hash(void *block, int length); - -#endif diff --git a/tests-old/TestCases/SimpleLFRic/util_mod.template b/tests-old/TestCases/SimpleLFRic/util_mod.template deleted file mode 100644 index b5100ca0..00000000 --- a/tests-old/TestCases/SimpleLFRic/util_mod.template +++ /dev/null @@ -1,29 +0,0 @@ -module util_mod - - use iso_c_binding, only : c_int, c_int8_t, c_loc, c_ptr - - implicit none - - private - public :: hash - - interface - function eor_hash(block, length) bind(c, name='eor_hash') - import c_int, c_int8_t, c_ptr - implicit none - integer(c_int8_t) eor_hash - type(c_ptr), intent(in) :: block - integer(c_int), intent(in), value :: length - end function eor_hash - end interface - -contains - - function hash(block) - implicit none - real, pointer :: block(:) - integer :: hash - hash = eor_hash(c_loc(block), size(block, 1)) - end function hash - -end module util_mod diff --git a/tests-old/TestCases/pFUnit/Build.txt b/tests-old/TestCases/pFUnit/Build.txt deleted file mode 100644 index 52d84952..00000000 --- a/tests-old/TestCases/pFUnit/Build.txt +++ /dev/null @@ -1,5 +0,0 @@ -stuff_test.o (Compile) - - stuff_test.F90 (pFUnit) - - stuff_test.pf -module.o (Compile) - - module.f90 diff --git a/tests-old/TestCases/pFUnit/Makefile b/tests-old/TestCases/pFUnit/Makefile deleted file mode 100644 index c1d304a6..00000000 --- a/tests-old/TestCases/pFUnit/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -# The best way to show how a test case should be built is to build it. -# While we don't have a build system we will use someone elses. -# -# This test simulates using the pFUnit framework for unit testing. -# As distributed it expects version 3.x.x of the framework. The -# processing script has changed name with version 4.x.x so you would -# need to change the PFRPOC macro to be "pfproc". -# -# The test assumes that the processing script is visible on the execution -# path. i.e. That it is included in the PATH environment variable. -# -.SUFFIXES: -.SUFFIXES: .pf .f90 .F90 .o .mod - -# By default gmake sets FC to "f77" we need to detect that and force it to our -# default. If it is not set then we still have a default but we allow the user -# to override it. -# -ifeq "$(origin FC)" "default" -export FC = ifort -else -export FC ?= ifort -endif - -PFPROC ?= pFUnitParser.py - -ifeq "x$(shell command -v $(PFPROC))" "x" -$(error Could not find the pFUnit processor on PATH) -endif - -objects: stuff_mod.o stuff_test.o - -.f90.o: - @echo Compiling $@ - $(FC) -o $@ -c $< - -.f90.mod: - @echo Compiling $@ - $(FC) -o $*.o -c $< - -.F90.o: - @echo Compiling $@ - $(FC) -o $@ -I$(PFUNIT)/mod -c $< - -.F90.mod: - @echo Compiling $@ - $(FC) -o $*.o -I$(PFUNIT)/mod -c $< - -.pf.F90: - @echo Processing $@ - $(PFPROC) $< $@ - -stuff_mod.o stuff_mod.mod: stuff_mod.f90 -stuff_test.o stuff_test_mod.mod: stuff_test.F90 stuff_mod.mod -stuff_test.F90: stuff_test.pf - -clean: - -rm *.o *.mod stuff_test.F90 diff --git a/tests-old/TestCases/pFUnit/stuff_mod.f90 b/tests-old/TestCases/pFUnit/stuff_mod.f90 deleted file mode 100644 index cbee2cca..00000000 --- a/tests-old/TestCases/pFUnit/stuff_mod.f90 +++ /dev/null @@ -1,17 +0,0 @@ -module stuff_mod - - implicit none - -contains - - function number() - - implicit none - - integer :: number - - number = 42 - - end function number - -end module stuff_mod diff --git a/tests-old/TestCases/pFUnit/stuff_test.pf b/tests-old/TestCases/pFUnit/stuff_test.pf deleted file mode 100644 index e9300aa7..00000000 --- a/tests-old/TestCases/pFUnit/stuff_test.pf +++ /dev/null @@ -1,22 +0,0 @@ -module stuff_test_mod - - use pFUnit_mod - use stuff_mod, only : number - - implicit none - -contains - - @test - subroutine test_number_okay() - - implicit none - - integer :: result - - result = number() - @assertEqual( 42, result ) - - end subroutine test_number_okay - -end module stuff_test_mod diff --git a/tests-old/system-tests/GitRepository/expected/aleph b/tests-old/system-tests/GitRepository/expected/aleph deleted file mode 100644 index 3c3670a7..00000000 --- a/tests-old/system-tests/GitRepository/expected/aleph +++ /dev/null @@ -1 +0,0 @@ -File the first. diff --git a/tests-old/system-tests/GitRepository/expected/beis/veis b/tests-old/system-tests/GitRepository/expected/beis/veis deleted file mode 100644 index 44a7476d..00000000 --- a/tests-old/system-tests/GitRepository/expected/beis/veis +++ /dev/null @@ -1,2 +0,0 @@ -File the second. - diff --git a/tests-old/system-tests/GitRepository/repo.tar b/tests-old/system-tests/GitRepository/repo.tar deleted file mode 100644 index 32b26270..00000000 Binary files a/tests-old/system-tests/GitRepository/repo.tar and /dev/null differ diff --git a/tests-old/system-tests/GitRepository_test.py b/tests-old/system-tests/GitRepository_test.py deleted file mode 100644 index f2267bfc..00000000 --- a/tests-old/system-tests/GitRepository_test.py +++ /dev/null @@ -1,17 +0,0 @@ -############################################################################## -# (c) Crown copyright Met Office. All rights reserved. -# For further details please refer to the file COPYRIGHT -# which you should have received as part of this distribution -############################################################################## -from pathlib import Path -from common import CompareFileTrees, RunGrab - -TEST_PATH = Path('system-tests') / Path(__file__).name.split('_test.py')[0] - - -def test_grab(): - # TODO: I can't test with the Git protocol as for some reason the - # Git daemon isn't installed. - command = RunGrab(TEST_PATH, 'git', 'file') - comparison = CompareFileTrees(command) - comparison.run() diff --git a/tests-old/system-tests/SubversionRepository/expected/trunk/alpha b/tests-old/system-tests/SubversionRepository/expected/trunk/alpha deleted file mode 100644 index e69de29b..00000000 diff --git a/tests-old/system-tests/SubversionRepository/expected/trunk/beta/gamma b/tests-old/system-tests/SubversionRepository/expected/trunk/beta/gamma deleted file mode 100644 index e69de29b..00000000 diff --git a/tests-old/system-tests/SubversionRepository/repo.tar b/tests-old/system-tests/SubversionRepository/repo.tar deleted file mode 100644 index 9aec198a..00000000 Binary files a/tests-old/system-tests/SubversionRepository/repo.tar and /dev/null differ diff --git a/tests-old/system-tests/SubversionRepository_test.py b/tests-old/system-tests/SubversionRepository_test.py deleted file mode 100644 index 396b51e7..00000000 --- a/tests-old/system-tests/SubversionRepository_test.py +++ /dev/null @@ -1,21 +0,0 @@ -############################################################################## -# (c) Crown copyright Met Office. All rights reserved. -# For further details please refer to the file COPYRIGHT -# which you should have received as part of this distribution -############################################################################## -from pathlib import Path -from common import CompareFileTrees, RunGrab - -TEST_PATH = Path('system-tests') / Path(__file__).name.split('_test.py')[0] - - -def test_grab_file(): - command = RunGrab(TEST_PATH, 'svn', 'file') - comparison = CompareFileTrees(command) - comparison.run() - - -def test_grab_svn(): - command = RunGrab(TEST_PATH, 'svn', 'svn') - comparison = CompareFileTrees(command) - comparison.run() diff --git a/tests-old/system-tests/common.py b/tests-old/system-tests/common.py deleted file mode 100644 index d9528ad9..00000000 --- a/tests-old/system-tests/common.py +++ /dev/null @@ -1,384 +0,0 @@ -############################################################################## -# (c) Crown copyright Met Office. All rights reserved. -# For further details please refer to the file COPYRIGHT -# which you should have received as part of this distribution -############################################################################## -""" -System testing for Fab. - -Currently runs the tool as a subprocess but should also use it as a library. -""" -from abc import ABC, ABCMeta, abstractmethod -import filecmp -import os.path -from pathlib import Path -import shutil -import subprocess -import sys -from tarfile import TarFile -import os -from typing import Dict, List, Optional, Sequence - - -class TestParameters(object): - """ - Holds information about the environment a test is happening in. - """ - def __init__(self, test_directory: Path, tag: str): - self._test_dir = test_directory - self._tag = tag - - @property - def test_directory(self): - return self._test_dir - - @property - def work_directory(self): - return self._test_dir / 'working' - - @property - def tag(self): - return self._tag - - -class RunCommand(ABC): - """ - Base class for tests containing useful utility functions. - """ - def __init__(self, - parameters: TestParameters, - command: List[str], - environment: Dict): - self._parameters = parameters - self._command = command - self._environment = environment - self._debug_output: Optional[List[str]] = None - - self.return_code: Optional[bool] = None - self.standard_out: Optional[str] = None - self.standard_error: Optional[str] = None - - @property - def test_parameters(self) -> TestParameters: - return self._parameters - - @abstractmethod - def description(self) -> str: - raise NotImplementedError("Abstract methods must be implemented.") - - @property - def debug_output(self) -> Optional[List[str]]: - return self._debug_output - - @debug_output.setter - def debug_output(self, additional_line: str): - if self._debug_output is None: - self._debug_output = [] - self._debug_output.append(additional_line) - - def set_up(self): - """ - Called prior to the run. - """ - pass - - def execute(self): - """ - Runs the command and changes state to reflect results. - """ - thread: subprocess.Popen = subprocess.Popen(self._command, - env=self._environment, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - stdout: bytes - stderr: bytes - stdout, stderr = thread.communicate() - self.return_code = thread.returncode - self.standard_out = stdout.decode('utf-8') - self.standard_error = stderr.decode('utf-8') - - if self.return_code != 0: - self._debug_output = ['Running command failed:'] - command = ' '.join(self._command) - self._debug_output.append(f' command: {command}') - self._debug_output.append(' stdout: ' + self.standard_out) - self._debug_output.append(' stderr: ' + self.standard_error) - - def tear_down(self): - """ - Called following the run. - """ - pass - - -class EnterPython(RunCommand, metaclass=ABCMeta): - """ - Run a Python entry point. - """ - def __init__(self, - tag: str, - test_directory: Path, - module: str, - args: Sequence[str] = (), - working_dir=True): - parameters = TestParameters(test_directory, tag) - - script = f'import sys; import fab.{module}; ' \ - f'sys.exit(fab.{module}.entry())' - command = ['python3', '-c', script] - if working_dir: - command.extend(['-w', str(parameters.work_directory)]) - command.extend(args) - - system_path = os.environ.get('PATH') or '' - user_path: List[str] = system_path.split(':') - try: - while True: - user_path.remove('') - except ValueError: - pass # No empty entries to be removed. - user_path.append(os.path.dirname(sys.executable)) - - environment = {'PATH': ':'.join(user_path), - 'PYTHONPATH': 'source'} - - super().__init__(parameters, command, environment) - self._working_dir = working_dir - - -class RunExec(RunCommand): - """ - Run an executable produced by fab. - """ - def __init__(self, test_directory: Path): - parameters = TestParameters(test_directory, 'exec') - args: List[str] = [] - executable = test_directory / 'working' / 'fab_test' - command = [str(executable)] + list(args) - super().__init__(parameters, command, {}) - - def description(self) -> str: - return f"{self.test_parameters.test_directory.stem} - Executing" - - -class RunFab(EnterPython): - """ - Run Fab build tool against a source tree. - """ - def __init__(self, - test_directory: Path, - target: str, - fpp_flags: str = None, - fc_flags: str = None, - ld_flags: str = None): - args: List[str] = [] - - if fpp_flags: - # different config file name for fpp flag test - self.conf_file = test_directory/('stay_config.ini') - else: - self.conf_file = test_directory/'config.ini' - - args.append(str(test_directory)) - args.append(str(self.conf_file)) - - with open(self.conf_file, 'wt') as configfile: - configfile.write('[settings] \n' - 'target = {}\n' - 'exec-name = fab_test \n' - '[flags] \n'.format(target)) - if fpp_flags: - configfile.write('fpp-flags = {}\n'.format(fpp_flags)) - else: - configfile.write('fpp-flags = ' + '\n') - if fc_flags: - configfile.write('fc-flags = {}\n'.format(fc_flags)) - else: - configfile.write('fc-flags = ' + '\n') - if ld_flags: - configfile.write('ld-flags = {}\n'.format(ld_flags)) - else: - configfile.write('ld-flags = ' + '\n') - super().__init__('fab', test_directory, 'builder', args) - - def description(self) -> str: - return f"{self.test_parameters.test_directory.stem} - Building" - - def set_up(self): - """ - Ensure there's no working directory left over from previous runs. - """ - if self.test_parameters.work_directory.is_dir(): - shutil.rmtree(self.test_parameters.work_directory) - - def tear_down(self): - """ - Clean up config files following the run. - """ - self.conf_file.unlink() - - -class RunDump(EnterPython): - """ - Run Fab dump tool against working directory. - """ - def __init__(self, test_directory: Path): - super().__init__('dump', test_directory, 'dumper') - - def description(self) -> str: - return f"{self.test_parameters.test_directory.stem} - Dumping" - - def teardown(self): - if self.test_parameters.work_directory.is_dir(): - shutil.rmtree(str(self.test_parameters.work_directory)) - - def tear_down(self): - """ - Tidy up now we're finished with the working directroy. - """ - shutil.rmtree(self.test_parameters.work_directory) - - -class RunGrab(EnterPython): - """ - Run Fab grab tool against a repository. - """ - def __init__(self, test_directory: Path, repo: str, protocol: str): - self._scheme = f"{repo}+{protocol}" - self._repo_path = test_directory.absolute() / "repo" - self._server: Optional[subprocess.Popen] = None - - if protocol == 'http': - # TODO: This scheme is included for completeness. Currently there - # is no obvious way to test this without an Apache server - # which is way too much to consider at the moment. - # repo_url = f'http://localhost/repo' - message = "Unable to test Fetch over HTTP protocol." - raise NotImplementedError(message) - - repo_url = f'{self._scheme}://' - if protocol == 'file': - repo_url += f'//{self._repo_path}' - # HTTP would be included here as well if we were able to test it. - elif protocol in ['git', 'svn']: - repo_url += 'localhost/' - else: - message = f"Unrecognised URL scheme '{self._scheme}'" - raise Exception(message) - - super().__init__('grab', - test_directory, - 'grabber', - [str(test_directory / 'working'), repo_url], - working_dir=False) - - def description(self) -> str: - name = self.test_parameters.test_directory.stem - return f"{name} - Grabbing with {self._scheme}" - - def set_up(self): - if self._repo_path.is_dir(): - shutil.rmtree(self._repo_path) - archiver = TarFile(self._repo_path.with_suffix('.tar')) - archiver.extractall(self._repo_path.parent) - - if self.test_parameters.work_directory.is_dir(): - shutil.rmtree(self.test_parameters.work_directory) - - if self._scheme.endswith('+git'): - # TODO: We would start the daemon here - raise NotImplementedError("Git protocol not supported") - elif self._scheme.endswith('+svn'): - command: List[str] = ['svnserve', '--root', str(self._repo_path), - '-X', '--foreground'] - self._server = subprocess.Popen(command) - - def tear_down(self): - shutil.rmtree(self.test_parameters.work_directory) - - if self._scheme.endswith('+git'): - # TODO: We would kill the daemon here - raise NotImplementedError("Git protocol not supported") - elif self._scheme.endswith('+svn'): - self._server.wait(timeout=1) - if self._server.returncode != 0: - message = f"Trouble with svnserve: {self._server.stderr}" - self.debug_output = message - - if self._repo_path.is_dir(): - shutil.rmtree(self._repo_path) - - -class CheckTask(ABC): - """ - Abstract parent of all checking test cases. - """ - def __init__(self, task: RunCommand, name: str): - self._name = name - self._task = task - - @property - def task(self): - return self._task - - def run(self): - self._task.set_up() - self._task.execute() - # - # We print this out for debug purposes. If a test fails this output - # should be visible. - # - if self._task.debug_output is not None: - print('\n'.join(self._task.debug_output)) - self.check() - self.task.tear_down() - - @abstractmethod - def check(self): - raise NotImplementedError("Abstract methods must be implemented.") - - -class CompareConsoleWithFile(CheckTask): - """ - Checks console output against expected result. - - The expected result is held in a file "expected.[.].txt. - Where "tag" comes from the task and "suffix" is specified. - """ - def __init__(self, task: RunCommand, expectation_suffix=None): - super().__init__(task, name=task.description()) - leaf_name = f'expected.{task.test_parameters.tag}' - if expectation_suffix is not None: - leaf_name = leaf_name + '.' + expectation_suffix - leaf_name = leaf_name + '.txt' - path = task.test_parameters.test_directory / leaf_name - self._expected = path.read_text() - - def check(self): - assert self.task.return_code == 0 - lines = self.task.standard_out - assert lines == self._expected - - -class CompareFileTrees(CheckTask): - """ - Checks filetree against expected result. - - The test tree is the tasks working directory and the expected result - is in "expected". - """ - def __init__(self, task: RunCommand): - super().__init__(task, name=task.description()) - self._expected = task.test_parameters.test_directory / 'expected' - - def check(self): - first = self.task.test_parameters.work_directory - second = self._expected - tree_comparison = filecmp.dircmp(first, second) - assert len(tree_comparison.left_only) == 0 - assert len(tree_comparison.right_only) == 0 - _, mismatch, errors = filecmp.cmpfiles(first, second, - tree_comparison.common_files, - shallow=False) - assert len(mismatch) == 0 - assert len(errors) == 0 diff --git a/tests-old/unit-tests/repository_test.py b/tests-old/unit-tests/repository_test.py deleted file mode 100644 index d9f878a3..00000000 --- a/tests-old/unit-tests/repository_test.py +++ /dev/null @@ -1,262 +0,0 @@ -############################################################################## -# (c) Crown copyright Met Office. All rights reserved. -# For further details please refer to the file COPYRIGHT -# which you should have received as part of this distribution -############################################################################## -""" -Exercise the 'repository' module. -""" -import filecmp -from pathlib import Path -from subprocess import run, Popen -import shutil -import signal -import time -from typing import List, Tuple - -from pytest import fixture, mark, raises # type: ignore -from _pytest.tmpdir import TempPathFactory # type: ignore - -from fab import FabException -from fab.repository import repository_from_url, GitRepo, SubversionRepo - - -def _tree_compare(first: Path, second: Path) -> None: - """ - Compare two file trees to ensure they are identical. - """ - tree_comparison = filecmp.dircmp(str(first), str(second)) - assert len(tree_comparison.left_only) == 0 \ - and len(tree_comparison.right_only) == 0 - _, mismatch, errors = filecmp.cmpfiles(str(first), str(second), - tree_comparison.common_files, - shallow=False) - assert len(mismatch) == 0 and len(errors) == 0 - - -class TestSubversion: - """ - Tests of the Subversion repository interface. - """ - @fixture(scope='class') - def repo(self, tmp_path_factory: TempPathFactory) -> Tuple[Path, Path]: - """ - Set up a repository and return its path along with the path of the - original file tree. - """ - repo_path = tmp_path_factory.mktemp('repo', numbered=True) - command = ['svnadmin', 'create', str(repo_path)] - assert run(command).returncode == 0 - tree_path = tmp_path_factory.mktemp('tree', numbered=True) - (tree_path / 'alpha').write_text("First file") - (tree_path / 'beta').mkdir() - (tree_path / 'beta' / 'gamma').write_text("Second file") - command = ['svn', 'import', '-m', "Initial import", - str(tree_path), f'file://{repo_path}/trunk'] - assert run(command).returncode == 0 - return repo_path, tree_path - - def test_extract_from_file(self, repo: Tuple[Path, Path], tmp_path: Path): - """ - Checks that a source tree can be extracted from a Subversion - repository stored on disc. - """ - test_unit = SubversionRepo(f'file://{repo[0]}/trunk') - test_unit.extract(tmp_path) - _tree_compare(repo[1], tmp_path) - assert not (tmp_path / '.svn').exists() - - def test_extract_from_svn(self, repo: Tuple[Path, Path], tmp_path: Path): - """ - Checks that a source tree can be extracted from a Subversion - repository accessed through its own protocol. - """ - command: List[str] = ['svnserve', '-r', str(repo[0]), '-X'] - process = Popen(command) - - test_unit = SubversionRepo('svn://localhost/trunk') - # - # It seems there can be a delay between the server starting and the - # listen socket opening. Thus we have a number of retries. - # - # TODO: Is there a better solution such that we don't try to connect - # until the socket is open? - # - for retry in range(3, 0, -1): - try: - test_unit.extract(tmp_path) - except FabException as ex: - if range == 0: - raise ex - time.sleep(1.0) - else: - break - _tree_compare(repo[1], tmp_path) - assert not (tmp_path / '.svn').exists() - - process.wait(timeout=1) - assert process.returncode == 0 - - @mark.skip(reason="Too hard to test at the moment.") - def test_extract_from_http(self, repo: Tuple[Path, Path], tmp_path: Path): - """ - Checks that a source tree can be extracted from a Subversion - repository accessed through HTTP. - - TODO: This is hard to test without a full Apache installation. For the - moment we forgo the test on the basis that it's too hard. - """ - pass - - -class TestGit: - """ - Tests of the Git repository interface. - """ - @fixture(scope='class') - def repo(self, tmp_path_factory: TempPathFactory) -> Tuple[Path, Path]: - """ - Set up a repository and return its path along with the path of the - original file tree. - """ - tree_path = tmp_path_factory.mktemp('tree', numbered=True) - (tree_path / 'alpha').write_text("First file") - (tree_path / 'beta').mkdir() - (tree_path / 'beta' / 'gamma').write_text("Second file") - - repo_path = tmp_path_factory.mktemp('repo', numbered=True) - command = ['git', 'init', str(repo_path)] - assert run(command).returncode == 0 - # - # We have to configure this information or the forthcoming commands - # will fail. - # - command = ['git', 'config', 'user.name', 'Testing Tester Tests'] - assert run(command, cwd=str(repo_path)).returncode == 0 - command = ['git', 'config', 'user.email', 'tester@example.com'] - assert run(command, cwd=str(repo_path)).returncode == 0 - - for file_object in tree_path.glob('*'): - if file_object.is_dir(): - shutil.copytree(str(file_object), - str(repo_path / file_object.name)) - else: - shutil.copy(str(file_object), - str(repo_path / file_object.name)) - command = ['git', 'add', '-A'] - assert run(command, cwd=str(repo_path)).returncode == 0 - command = ['git', 'commit', '-m', "Initial import"] - assert run(command, cwd=str(repo_path)).returncode == 0 - return repo_path.absolute(), tree_path.absolute() - - def test_extract_from_file(self, repo: Tuple[Path, Path], tmp_path: Path): - """ - Tests that a source tree can be extracted from a local repository. - """ - test_unit = GitRepo(f'file://{repo[0]}') - test_unit.extract(tmp_path) - _tree_compare(repo[1], tmp_path) - assert not (tmp_path / '.git').exists() - - def test_missing_repo(self, tmp_path: Path): - """ - Tests that an error is returned if the repository is not there. - """ - fake_repo = tmp_path / "nonsuch.repo" - fake_repo.mkdir() - test_unit = GitRepo(f'file://{fake_repo}') - with raises(FabException) as ex: - test_unit.extract(tmp_path / 'working') - expected = "Fault exporting tree from Git repository:" - assert str(ex.value).startswith(expected) - - @mark.skip(reason="The daemon doesn't seem to be installed.") - def test_extract_from_git(self, repo: Tuple[Path, Path], tmp_path: Path): - """ - Checks that a source tree can be extracted from a Git repository - accessed through its own protocol. - """ - command: List[str] = ['git', 'daemon', '--reuseaddr', - '--base-path='+str(repo[0].parent), - str(repo[0])] - process = Popen(command) - - test_unit = GitRepo('git://localhost/'+repo[0].name) - test_unit.extract(tmp_path) - _tree_compare(repo[1], tmp_path) - assert not (tmp_path / '.git').exists() - - process.send_signal(signal.SIGTERM) - process.wait(timeout=2) - assert process.returncode == -15 - - @mark.skip(reason="Too hard to test at the moment.") - def test_extract_from_http(self, repo: Tuple[Path, Path], tmp_path: Path): - """ - Checks that a source tree can be extracted from a Git repository - accessed through HTTP. - - TODO: This is hard to test without a full Apache installation. For the - moment we forgo the test on the basis that it's too hard. - """ - pass - - -class TestRepoFromURL: - """ - Tests that a URL can be converted into the correct Repository object. - """ - @fixture(scope='class', - params=[ - {'access_url': 'git://example.com/git', - 'repo_class': GitRepo, - 'repo_url': 'git://example.com/git'}, - {'access_url': 'git+file:///tmp/git', - 'repo_class': GitRepo, - 'repo_url': 'file:///tmp/git'}, - {'access_url': 'git+git://example.com/git', - 'repo_class': GitRepo, - 'repo_url': 'git://example.com/git'}, - {'access_url': 'git+http://example.com/git', - 'repo_class': GitRepo, - 'repo_url': 'http://example.com/git'}, - {'access_url': 'svn://example.com/svn', - 'repo_class': SubversionRepo, - 'repo_url': 'svn://example.com/svn'}, - {'access_url': 'svn+file:///tmp/svn', - 'repo_class': SubversionRepo, - 'repo_url': 'file:///tmp/svn'}, - {'access_url': 'svn+http://example.com/svn', - 'repo_class': SubversionRepo, - 'repo_url': 'http://example.com/svn'}, - {'access_url': 'svn+svn://example.com/svn', - 'repo_class': SubversionRepo, - 'repo_url': 'svn://example.com/svn'}, - {'access_url': 'file:///tmp/repo', - 'repo_class': FabException, - 'exception': "Unrecognised repository scheme: file+file"}, - {'access_url': 'http://example.com/repo', - 'repo_class': FabException, - 'exception': "Unrecognised repository scheme: http+http"}, - {'access_url': 'foo+file:///tmp/foo', - 'repo_class': FabException, - 'exception': "Unrecognised repository scheme: foo+file"} - ]) - def cases(self, request): - """ - Generates a set of test cases. - """ - yield request.param - - def test_action(self, cases): - """ - Checks that each URL creates an appropriate Repository object. - """ - if issubclass(cases['repo_class'], Exception): - with raises(cases['repo_class']) as ex: - _ = repository_from_url(cases['access_url']) - assert ex.value.args[0] == cases['exception'] - else: - repo = repository_from_url(cases['access_url']) - assert isinstance(repo, cases['repo_class']) - assert repo.url == cases['repo_url'] diff --git a/tests-old/unit-tests/tasks/__init__.py b/tests-old/unit-tests/tasks/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests-old/unit-tests/tasks/c_test.py b/tests-old/unit-tests/tasks/c_test.py deleted file mode 100644 index 3d188af6..00000000 --- a/tests-old/unit-tests/tasks/c_test.py +++ /dev/null @@ -1,64 +0,0 @@ -############################################################################## -# (c) Crown copyright Met Office. All rights reserved. -# For further details please refer to the file COPYRIGHT -# which you should have received as part of this distribution -############################################################################## -from pathlib import Path -from textwrap import dedent - - -class TestCPragmaInjector: - def test_run(self, tmp_path): - workspace = tmp_path / 'working' - workspace.mkdir() - - test_file: Path = tmp_path / 'test.c' - test_file.write_text( - dedent(''' - #include "user_include.h" - Unrelated text - #include 'another_user_include.h' - #include - More unrelated text - #include - ''')) - test_artifact = Artifact(test_file, - CSource, - HeadersAnalysed) - test_artifact.add_dependency('foo') - - # Run the Injector - injector = CPragmaInjector(workspace) - artifacts_out = injector.run([test_artifact]) - - assert len(artifacts_out) == 1 - assert artifacts_out[0].location == workspace / 'test.c' - assert artifacts_out[0].filetype is CSource - assert artifacts_out[0].state is Modified - assert artifacts_out[0].depends_on == ['foo'] - assert artifacts_out[0].defines == [] - - new_file = workspace / 'test.c' - assert new_file.exists() - with new_file.open('r') as fh: - new_text = fh.read() - - expected_text = ( - dedent(''' - #pragma FAB UsrIncludeStart - #include "user_include.h" - #pragma FAB UsrIncludeEnd - Unrelated text - #pragma FAB UsrIncludeStart - #include 'another_user_include.h' - #pragma FAB UsrIncludeEnd - #pragma FAB SysIncludeStart - #include - #pragma FAB SysIncludeEnd - More unrelated text - #pragma FAB SysIncludeStart - #include - #pragma FAB SysIncludeEnd - ''')) - - assert new_text == expected_text diff --git a/tests-old/unit-tests/tasks/common_test.py b/tests-old/unit-tests/tasks/common_test.py deleted file mode 100644 index 1ab27b9e..00000000 --- a/tests-old/unit-tests/tasks/common_test.py +++ /dev/null @@ -1,58 +0,0 @@ -############################################################################## -# (c) Crown copyright Met Office. All rights reserved. -# For further details please refer to the file COPYRIGHT -# which you should have received as part of this distribution -############################################################################## -from pathlib import Path -from textwrap import dedent - -from fab.tasks.common import Linker, HeaderAnalyser -from fab.artifact import \ - Artifact, \ - New, \ - Unknown, \ - Executable, \ - Linked, \ - HeadersAnalysed - - -class TestLinker: - def test_run(self, mocker, tmp_path: Path): - # Instantiate Linker - workspace = Path(tmp_path) - linker = Linker('foo', - ['--bar', '--baz'], - workspace, - 'qux') - - # Create artifacts (object files for linking) - file1 = '/path/to/file.1' - file2 = '/path/to/file.2' - artifacts = [Artifact(Path(file1), - Unknown, - New), - Artifact(Path(file2), - Unknown, - New)] - - # Monkeypatch the subprocess call out and run linker - patched_run = mocker.patch('subprocess.run') - artifacts_out = linker.run(artifacts) - - # Check that the subprocess call contained the command - # that we would expect based on the above - expected_command = ['foo', - '-o', - str(workspace / 'qux'), - file1, - file2, - '--bar', - '--baz'] - patched_run.assert_called_once_with(expected_command, - check=True) - assert len(artifacts_out) == 1 - assert artifacts_out[0].location == workspace / 'qux' - assert artifacts_out[0].filetype is Executable - assert artifacts_out[0].state is Linked - assert artifacts_out[0].depends_on == [] - assert artifacts_out[0].defines == [] diff --git a/tests/unit_tests/parse/c/test_c_analyser.py b/tests/unit_tests/parse/c/test_c_analyser.py index b4f84c94..c288baf9 100644 --- a/tests/unit_tests/parse/c/test_c_analyser.py +++ b/tests/unit_tests/parse/c/test_c_analyser.py @@ -7,12 +7,14 @@ from unittest import mock from unittest.mock import Mock -import clang # type: ignore +from pytest import importorskip from fab.build_config import BuildConfig from fab.parse.c import CAnalyser, AnalysedC from fab.tools import ToolBox +clang = importorskip('clang') + def test_simple_result(tmp_path): c_analyser = CAnalyser() diff --git a/tests/unit_tests/steps/test_c_pragma_injector.py b/tests/unit_tests/steps/test_c_pragma_injector.py index e75e9f19..666bae1b 100644 --- a/tests/unit_tests/steps/test_c_pragma_injector.py +++ b/tests/unit_tests/steps/test_c_pragma_injector.py @@ -1,4 +1,5 @@ -import sys +from sys import version_info as python_version +from textwrap import dedent from unittest import mock from unittest.mock import mock_open @@ -9,32 +10,52 @@ class Test_inject_pragmas(object): - @pytest.mark.skipif(sys.version_info < (3, 8), reason="requires python3.8 or higher for mock_open iteration") + @pytest.mark.skipif(python_version < (3, 8), + reason="Requires python version 3.8 or higher for " + "mock_open iteration") def test_vanilla(self): - input = [ - '', - '// hi there, ignore me', - '', - '#include ', - '', - '#include "bar.h"', - '', - ] - data = "\n".join(input) + source = dedent( + """ + // C++ style comment, ignore this. + #include "user_include.h" + #include "second_user_include.h" + Unrelated text + /* Including C style comment */ + #include 'another_user_include.h' + #include + More unrelated text + #include + #include "final_user_include.h" + """ + ) - with mock.patch('fab.steps.c_pragma_injector.open', mock_open(read_data=data)): + with mock.patch('fab.steps.c_pragma_injector.open', + mock_open(read_data=source)): result = inject_pragmas(fpath="foo") output = list(result) assert output == [ '\n', - '// hi there, ignore me\n', - '\n', + '// C++ style comment, ignore this.\n', + '#pragma FAB UsrIncludeStart\n', + '#include "user_include.h"\n', + '#pragma FAB UsrIncludeEnd\n', + '#pragma FAB UsrIncludeStart\n', + '#include "second_user_include.h"\n', + '#pragma FAB UsrIncludeEnd\n', + 'Unrelated text\n', + '/* Including C style comment */\n', + '#pragma FAB UsrIncludeStart\n', + "#include 'another_user_include.h'\n", + '#pragma FAB UsrIncludeEnd\n', '#pragma FAB SysIncludeStart\n', - '#include \n', + '#include \n', + '#pragma FAB SysIncludeEnd\n', + "More unrelated text\n", + '#pragma FAB SysIncludeStart\n', + '#include \n', '#pragma FAB SysIncludeEnd\n', - '\n', '#pragma FAB UsrIncludeStart\n', - '#include "bar.h"\n', - '#pragma FAB UsrIncludeEnd\n', + '#include "final_user_include.h"\n', + '#pragma FAB UsrIncludeEnd\n' ] diff --git a/tests/unit_tests/tools/test_compiler.py b/tests/unit_tests/tools/test_compiler.py index 6bfcece7..c31e480e 100644 --- a/tests/unit_tests/tools/test_compiler.py +++ b/tests/unit_tests/tools/test_compiler.py @@ -642,15 +642,15 @@ def test_ifort_get_version_with_icc_string(): "0.5.1.", "0.5..1"]) def test_ifort_get_version_invalid_version(version): - '''Tests the icc class with an icc version string that contains an invalid - version number.''' + '''Tests the ifort class with an ifort version string that contains an + invalid version number.''' full_output = dedent(f""" - icc (ICC) {version} 20230609 - Copyright (C) 1985-2023 Intel Corporation. All rights reserved. + ifort (IFORT) {version} 20140422 + Copyright (C) 1985-2014 Intel Corporation. All rights reserved. """) - icc = Ifort() - with mock.patch.object(icc, "run", mock.Mock(return_value=full_output)): + ifort = Ifort() + with mock.patch.object(ifort, "run", mock.Mock(return_value=full_output)): with pytest.raises(RuntimeError) as err: - icc.get_version() + ifort.get_version() assert "Unexpected version output format for compiler" in str(err.value) diff --git a/tests/unit_tests/tools/test_versioning.py b/tests/unit_tests/tools/test_versioning.py index a3b21896..fb825000 100644 --- a/tests/unit_tests/tools/test_versioning.py +++ b/tests/unit_tests/tools/test_versioning.py @@ -3,28 +3,26 @@ # For further details please refer to the file COPYRIGHT # which you should have received as part of this distribution ############################################################################## - -'''Tests the compiler implementation. -''' - +""" +Tests version control interfaces. +""" +from filecmp import cmpfiles, dircmp +from pathlib import Path +from shutil import which from unittest import mock +from subprocess import Popen, run +from time import sleep +from typing import List, Tuple -import pytest +from pytest import TempPathFactory, fixture, mark, raises -from fab.tools import Category, Fcm, Git, Subversion, Versioning +from fab.tools import Category, Fcm, Git, Subversion class TestGit: - '''Contains all git related tests.''' - - def test_versioning_constructor(self): - '''Test the versioning constructor.''' - versioning = Versioning("versioning", "versioning.exe", Category.GIT) - assert versioning.category == Category.GIT - assert versioning.name == "versioning" - assert versioning.flags == [] - assert versioning.exec_name == "versioning.exe" - + """ + Tests of the Git repository interface. + """ def test_git_constructor(self): '''Test the git constructor.''' git = Git() @@ -116,7 +114,7 @@ def test_git_fetch(self): with mock.patch.object(git, "run", side_effect=RuntimeError("ERR")) as run: - with pytest.raises(RuntimeError) as err: + with raises(RuntimeError) as err: git.fetch("/src", "/dst", revision="revision") assert "ERR" in str(err.value) run.assert_called_once_with(['fetch', "/src", "revision"], cwd="/dst", @@ -143,7 +141,7 @@ def test_git_checkout(self): with mock.patch.object(git, "run", side_effect=RuntimeError("ERR")) as run: - with pytest.raises(RuntimeError) as err: + with raises(RuntimeError) as err: git.checkout("/src", "/dst", revision="revision") assert "ERR" in str(err.value) run.assert_called_with(['fetch', "/src", "revision"], cwd="/dst", @@ -173,7 +171,7 @@ def raise_1st_time(): with mock.patch.object(git, "run", side_effect=raise_1st_time()) as run: - with pytest.raises(RuntimeError) as err: + with raises(RuntimeError) as err: git.merge("/dst", revision="revision") assert "Error merging revision. Merge aborted." in str(err.value) run.assert_any_call(['merge', "FETCH_HEAD"], cwd="/dst", @@ -184,7 +182,7 @@ def raise_1st_time(): # Test behaviour if both merge and merge --abort fail with mock.patch.object(git, "run", side_effect=RuntimeError("ERR")) as run: - with pytest.raises(RuntimeError) as err: + with raises(RuntimeError) as err: git.merge("/dst", revision="revision") assert "ERR" in str(err.value) run.assert_called_with(['merge', "--abort"], cwd="/dst", @@ -192,22 +190,27 @@ def raise_1st_time(): # ============================================================================ -class TestSvn: - '''Contains all svn related tests.''' - +class TestSubversion: + """ + Tests the Subversion interface. + """ def test_svn_constructor(self): - '''Test the git constructor.''' + """ + Test the git constructor. + """ svn = Subversion() assert svn.category == Category.SUBVERSION assert svn.flags == [] - assert svn.name == "subversion" + assert svn.name == "Subversion" assert svn.exec_name == "svn" def test_svn_export(self): - '''Check export svn functionality. The tests here will actually - mock the git results, so they will work even if subversion is not - installed. The system_tests will test an actual check out etc. ''' + """ + Ensures an export from repository works. + Subversion is mocked here to allow testing without the executable. + Testing with happens below in TestSubversionReal. + """ svn = Subversion() mock_result = mock.Mock(returncode=0) with mock.patch('fab.tools.tool.subprocess.run', @@ -282,14 +285,107 @@ def test_svn_merge(self): env=None, cwd="/dst", capture_output=True, check=False) +def _tree_compare(first: Path, second: Path) -> None: + """ + Compare two file trees to ensure they are identical. + """ + tree_comparison = dircmp(str(first), str(second)) + assert len(tree_comparison.left_only) == 0 \ + and len(tree_comparison.right_only) == 0 + _, mismatch, errors = cmpfiles(str(first), str(second), + tree_comparison.common_files, + shallow=False) + assert len(mismatch) == 0 and len(errors) == 0 + + +@mark.skipif(which('svn') is None, + reason="No Subversion executable found on path.") +class TestSubversionReal: + """ + Tests the Subversion interface against a real executable. + """ + @fixture(scope='class') + def repo(self, tmp_path_factory: TempPathFactory) -> Tuple[Path, Path]: + """ + Set up a repository and return its path along with the path of the + original file tree. + """ + repo_path = tmp_path_factory.mktemp('repo', numbered=True) + command = ['svnadmin', 'create', str(repo_path)] + assert run(command).returncode == 0 + tree_path = tmp_path_factory.mktemp('tree', numbered=True) + (tree_path / 'alpha').write_text("First file") + (tree_path / 'beta').mkdir() + (tree_path / 'beta' / 'gamma').write_text("Second file") + command = ['svn', 'import', '-m', "Initial import", + str(tree_path), f'file://{repo_path}/trunk'] + assert run(command).returncode == 0 + return repo_path, tree_path + + def test_extract_from_file(self, repo: Tuple[Path, Path], tmp_path: Path): + """ + Checks that a source tree can be extracted from a Subversion + repository stored on disc. + """ + test_unit = Subversion() + test_unit.export(f'file://{repo[0]}/trunk', tmp_path) + _tree_compare(repo[1], tmp_path) + assert not (tmp_path / '.svn').exists() + + def test_extract_from_svn(self, repo: Tuple[Path, Path], tmp_path: Path): + """ + Checks that a source tree can be extracted from a Subversion + repository accessed through its own protocol. + """ + command: List[str] = ['svnserve', '-r', str(repo[0]), '-X'] + process = Popen(command) + + test_unit = Subversion() + # + # It seems there can be a delay between the server starting and the + # listen socket opening. Thus we have a number of retries. + # + # TODO: Is there a better solution such that we don't try to connect + # until the socket is open? + # + for retry in range(3, 0, -1): + try: + test_unit.export('svn://localhost/trunk', tmp_path) + except Exception as ex: + if range == 0: + raise ex + sleep(1.0) + else: + break + _tree_compare(repo[1], tmp_path) + assert not (tmp_path / '.svn').exists() + + process.wait(timeout=1) + assert process.returncode == 0 + + @mark.skip(reason="Too hard to test at the moment.") + def test_extract_from_http(self, repo: Tuple[Path, Path], tmp_path: Path): + """ + Checks that a source tree can be extracted from a Subversion + repository accessed through HTTP. + + TODO: This is hard to test without a full Apache installation. For the + moment we forgo the test on the basis that it's too hard. + """ + pass + + # ============================================================================ class TestFcm: - '''Contains all FCM related tests.''' - + """ + Tests the FCM interface task. + """ def test_fcm_constructor(self): - '''Test the fcb constructor.''' + """ + Tests this constructor. + """ fcm = Fcm() assert fcm.category == Category.FCM assert fcm.flags == [] - assert fcm.name == "fcm" + assert fcm.name == "FCM" assert fcm.exec_name == "fcm"