mirror of
https://github.com/cpm-cmake/CPM.cmake.git
synced 2025-11-19 07:37:42 -05:00
First integration test
This commit is contained in:
1
test/integration/.gitignore
vendored
1
test/integration/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
tmp/
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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?
|
||||
}
|
||||
11
test/integration/templates/using-adder/lists.in.cmake
Normal file
11
test/integration/templates/using-adder/lists.in.cmake
Normal file
@@ -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)
|
||||
@@ -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
|
||||
48
test/integration/test_simple.rb
Normal file
48
test/integration/test_simple.rb
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user