From 10c24fc8aff3cfb0f41ab3b3d566cd6919a7cf98 Mon Sep 17 00:00:00 2001 From: Borislav Stanimirov Date: Tue, 11 Jan 2022 07:51:46 +0200 Subject: [PATCH] First integration test --- test/integration/.gitignore | 1 - test/integration/lib.rb | 106 +++++++++----- test/integration/runner-old.rb | 131 ------------------ test/integration/simple-old.rb | 10 -- .../templates/using-adder/lists.in.cmake | 11 ++ .../using-adder}/using-adder.cpp | 0 test/integration/test_noop.rb | 9 -- test/integration/test_simple.rb | 48 +++++++ 8 files changed, 134 insertions(+), 182 deletions(-) delete mode 100644 test/integration/.gitignore delete mode 100644 test/integration/runner-old.rb delete mode 100644 test/integration/simple-old.rb create mode 100644 test/integration/templates/using-adder/lists.in.cmake rename test/integration/{ => templates/using-adder}/using-adder.cpp (100%) delete mode 100644 test/integration/test_noop.rb create mode 100644 test/integration/test_simple.rb diff --git a/test/integration/.gitignore b/test/integration/.gitignore deleted file mode 100644 index 3fec32c..0000000 --- a/test/integration/.gitignore +++ /dev/null @@ -1 +0,0 @@ -tmp/ diff --git a/test/integration/lib.rb b/test/integration/lib.rb index 0d7b465..5a5f347 100644 --- a/test/integration/lib.rb +++ b/test/integration/lib.rb @@ -3,38 +3,66 @@ require 'open3' require 'tmpdir' require 'test/unit' -TestTmpDir = File.join(Dir.tmpdir, "cpm-itest-#{Time.now.strftime('%Y_%m_%d-%H_%M_%S')}") -raise "Test directory '#{TestTmpDir}' already exists" if File.exist?(TestTmpDir) +module TestLib + TMP_DIR = File.join(Dir.tmpdir, 'cpm-test', Time.now.strftime('%Y_%m_%d-%H_%M_%S')) + CPM_PATH = File.expand_path('../../cmake/CPM.cmake', __dir__) + + TEMPLATES_DIR = File.expand_path('templates', __dir__) + + # Environment variables which are read by cpm + CPM_ENV = %w( + CPM_USE_LOCAL_PACKAGES + CPM_LOCAL_PACKAGES_ONLY + CPM_DOWNLOAD_ALL + CPM_DONT_UPDATE_MODULE_PATH + CPM_DONT_CREATE_PACKAGE_LOCK + CPM_INCLUDE_ALL_IN_PACKAGE_LOCK + CPM_USE_NAMED_CACHE_DIRECTORIES + CPM_SOURCE_CACHE + ) + def self.clear_env + CPM_ENV.each { ENV[_1] = nil } + end +end + +raise "Test directory '#{TestLib::TMP_DIR}' already exists" if File.exist?(TestLib::TMP_DIR) +raise "Cannot find 'CPM.cmake' at '#{TestLib::CPM_PATH}'" if !File.file?(TestLib::CPM_PATH) puts "Running CPM.cmake integration tests" -puts "Temp directory: '#{TestTmpDir}'" - -CPMPath = File.expand_path('../../cmake/CPM.cmake', __dir__) -raise "Cannot find 'CPM.cmake' at '#{CPMPath}'" if !File.file?(CPMPath) - -# Environment variables which are read by cpm -CPM_ENV = %w( - CPM_USE_LOCAL_PACKAGES - CPM_LOCAL_PACKAGES_ONLY - CPM_DOWNLOAD_ALL - CPM_DONT_UPDATE_MODULE_PATH - CPM_DONT_CREATE_PACKAGE_LOCK - CPM_INCLUDE_ALL_IN_PACKAGE_LOCK - CPM_USE_NAMED_CACHE_DIRECTORIES - CPM_SOURCE_CACHE -) - -# Clear existing cpm-related env vars -CPM_ENV.each { ENV[_1] = nil } +puts "Temp directory: '#{TestLib::TMP_DIR}'" class Project - def initialize(dir, name) - @name = name - d = File.join(TestTmpDir, dir) - @src_dir = d + '-src' - @build_dir = d + '-build' - p @src_dir - FileUtils.mkdir_p [@src_dir, @build_dir] + def initialize(src_dir, build_dir) + @src_dir = src_dir + @build_dir = build_dir + end + + def create_file(target_path, text) + target_path = File.join(@src_dir, target_path) + File.write target_path, text + end + + def create_file_with(target_path, source_path, args) + source_path = File.join(@src_dir, source_path) + raise "#{source_path} doesn't exist" if !File.file?(source_path) + + # tweak args + args[:cpm_path] = TestLib::CPM_PATH + args[:packages] = [args[:package]] if args[:package] # if args contain package, create the array + args[:packages] = args[:packages].join("\n") # join all packages + + src_text = File.read source_path + create_file target_path, src_text % args + end + + # common function to create ./CMakeLists.txt from ./lists.in.cmake + def create_lists_with(args) + create_file_with 'CMakeLists.txt', 'lists.in.cmake', args + end + + CommandResult = Struct.new :out, :err, :status + def configure(extra_args = '') + CommandResult.new *Open3.capture3("cmake -S #{@src_dir} -B #{@build_dir} #{extra_args}") end class CMakeCacheValue @@ -72,10 +100,26 @@ class Project end class IntegrationTest < Test::Unit::TestCase - def make_project(name = nil) + def setup + # Clear existing cpm-related env vars + TestLib.clear_env + end + + def make_project(template_dir = nil) test_name = local_name test_name = test_name[5..] if test_name.start_with?('test_') - name = test_name if !name - Project.new "#{self.class.name.downcase}-#{test_name}", name + + base = File.join(TestLib::TMP_DIR, self.class.name.downcase, test_name) + src_dir = base + '-src' + + FileUtils.mkdir_p src_dir + + if template_dir + template_dir = File.join(TestLib::TEMPLATES_DIR, template_dir) + raise "#{template_dir} is not a directory" if !File.directory?(template_dir) + FileUtils.copy_entry template_dir, src_dir + end + + Project.new src_dir, base + '-build' end end diff --git a/test/integration/runner-old.rb b/test/integration/runner-old.rb deleted file mode 100644 index db7cc97..0000000 --- a/test/integration/runner-old.rb +++ /dev/null @@ -1,131 +0,0 @@ -require 'fileutils' -require 'open3' - -CPMPath = File.expand_path('../../cmake/CPM.cmake', __dir__) -raise "Cannot file 'CPM.cmake' at '#{CPMPath}'" if !File.file?(CPMPath) - -CommonHeader = <<~CMAKE - cmake_minimum_required(VERSION 3.14 FATAL_ERROR) - include("#{CPMPath}") - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") -CMAKE - -TestDir = File.expand_path("./tmp/#{Time.now.strftime('%Y_%m_%d-%H_%M_%S')}") -raise "Test directory '#{TestDir}' already exists" if File.exist?(TestDir) - -puts "Running CPM.cmake integration tests" -puts "Temp directory: '#{TestDir}'" - -class CMakeListsBuilder - def initialize - @contents = '' - end - def literal(lit) - @contents += lit + "\n"; - self - end - def package(pack) - literal "CPMAddPackage(#{pack})" - end - def exe(exe, sources) - @contents += "add_executable(#{exe}\n" - @contents += sources.map { |src| - ' ' + if src['/'] - src - else - File.expand_path("#{src}", __dir__) - end - }.join("\n") - @contents += "\n)\n" - self - end - def link_libs(target, libs) - literal "target_link_libraries(#{target} #{libs})\n" - end - def to_s - @contents - end -end - -class ExecuteResult - def initialize(out, err, status) - @out = out - @err = err - @status = status - end - attr :out, :err, :status -end - -class Project - def initialize(name) - @name = name - @dir = File.join(TestDir, name) - - FileUtils.mkdir_p(File.join(TestDir, name)) - end - - def build_cmake_lists(opts = {}, &block) - builder = CMakeListsBuilder.new - if !opts[:no_default_header] - builder.literal(CommonHeader) - builder.literal("project(#{@name})") - end - text = builder.instance_eval &block - - File.write(File.join(@dir, 'CMakeLists.txt'), text) - end - - def configure(args = '') - ExecuteResult.new *Open3.capture3("cmake . #{args}", chdir: @dir) - end -end - -@cur_file = '' -@tests = {} -def add_test(name, func) - raise "#{@cur_file}: Test #{name} is already defined from another file" if @tests[name] - @tests[name] = func -end - -# check funcs -class CheckFail < StandardError - def initialize(msg) - super - end -end - -def check(b) - raise CheckFail.new "expected 'true'" if !b -end - -Dir['tests/*.rb'].sort.each do |file| - @cur_file = file - load './' + file -end - -# sort alphabetically -sorted_tests = @tests.to_a.sort {|a, b| a[0] <=> b[0] } - -num_succeeded = 0 -num_failed = 0 - -sorted_tests.each do |name, func| - puts "Running '#{name}'" - proj = Project.new(name) - begin - func.(proj) - num_succeeded += 1 - puts ' success' - rescue CheckFail => error - num_failed += 1 - STDERR.puts " #{name}: check failed '#{error.message}'" - STDERR.puts " backtrace:\n #{error.backtrace.join("\n ")}" - STDERR.puts - end -end - -puts "Ran #{num_succeeded + num_failed} tests" -puts "Succeeded: #{num_succeeded}" -puts "Failed: #{num_failed}" - -exit(num_failed) diff --git a/test/integration/simple-old.rb b/test/integration/simple-old.rb deleted file mode 100644 index 787a28b..0000000 --- a/test/integration/simple-old.rb +++ /dev/null @@ -1,10 +0,0 @@ -add_test 'basic', ->(prj) { - prj.build_cmake_lists { - package 'gh:cpm-cmake/testpack-adder' - exe 'using-adder', ['using-adder.cpp'] - link_libs 'using-adder', 'adder' - } - cfg = prj.configure - - check cfg.status.success? -} diff --git a/test/integration/templates/using-adder/lists.in.cmake b/test/integration/templates/using-adder/lists.in.cmake new file mode 100644 index 0000000..4d0d428 --- /dev/null +++ b/test/integration/templates/using-adder/lists.in.cmake @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.14 FATAL_ERROR) + +project(using-adder) + +include("%{cpm_path}") + +%{packages} + +add_executable(using-adder using-adder.cpp) + +target_link_libraries(using-adder adder) diff --git a/test/integration/using-adder.cpp b/test/integration/templates/using-adder/using-adder.cpp similarity index 100% rename from test/integration/using-adder.cpp rename to test/integration/templates/using-adder/using-adder.cpp diff --git a/test/integration/test_noop.rb b/test/integration/test_noop.rb deleted file mode 100644 index 4762b5d..0000000 --- a/test/integration/test_noop.rb +++ /dev/null @@ -1,9 +0,0 @@ -# this test does nothing -# it's, in a way, a test of the integration testing framework -require './lib' - -class Noop < IntegrationTest - def test_tt - make_project - end -end diff --git a/test/integration/test_simple.rb b/test/integration/test_simple.rb new file mode 100644 index 0000000..5485301 --- /dev/null +++ b/test/integration/test_simple.rb @@ -0,0 +1,48 @@ +require './lib' + +class Simple < IntegrationTest + def get_adder_data(cache) + [ + cache['CPM_PACKAGE_testpack-adder_VERSION'].val, + cache['CPM_PACKAGE_testpack-adder_SOURCE_DIR'].val, + cache['CPM_PACKAGE_testpack-adder_BINARY_DIR'].val, + ] + end + + def test_basics + prj = make_project 'using-adder' + + prj.create_lists_with package: 'CPMAddPackage("gh:cpm-cmake/testpack-adder#cad1cd4b4cdf957c5b59e30bc9a1dd200dbfc716")' + cfg_result = prj.configure + + assert cfg_result.status.success? + + cache = prj.read_cache + + assert_equal 'testpack-adder', cache['CPM_PACKAGES'].val + + ver, src, bin = get_adder_data cache + + assert_equal ver, '0' + assert File.directory? src + assert File.directory? bin + + adder_ver_file = File.join(src, 'version') + assert File.file? adder_ver_file + assert_equal 'initial', File.read(adder_ver_file).strip + + # reconfigure with new version + prj.create_lists_with package: 'CPMAddPackage("gh:cpm-cmake/testpack-adder@1.0.0")' + cfg_result = prj.configure + + cache_new = prj.read_cache + ver, src, bin = get_adder_data cache_new + + assert_equal '1.0.0', ver + + # dir shouldn't have changed + assert_equal File.dirname(adder_ver_file), src + + assert_equal '1.0.0', File.read(adder_ver_file).strip + end +end