From 4c8727182ebcb28f0f6142298209e7fc82cd0f78 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Fri, 13 Sep 2019 18:54:31 +0200 Subject: [PATCH 1/2] Fixed #354 by using the proper initialization --- src/buddies/src/bd/bdInit.cc | 15 ++++++++++++++- src/buddies/src/bd/strmrun.cc | 8 -------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/buddies/src/bd/bdInit.cc b/src/buddies/src/bd/bdInit.cc index ddfc7051e..6fd95db14 100644 --- a/src/buddies/src/bd/bdInit.cc +++ b/src/buddies/src/bd/bdInit.cc @@ -21,9 +21,12 @@ */ #include "bdInit.h" +#include "dbInit.h" #include "tlCommandLineParser.h" #include "tlProgress.h" #include "version.h" +#include "gsi.h" +#include "gsiExpression.h" #include @@ -48,8 +51,18 @@ void init () license += "\n"; license += prg_about_text; tl::CommandLineOptions::set_license (license); -} + // initialize db plugins + db::init (); + + // initialize the GSI class system (Variant binding, Expression support) + // We have to do this now since plugins may register GSI classes and before the + // ruby interpreter, because it depends on a proper class system. + gsi::initialize (); + + // initialize the tl::Expression subsystem with GSI-bound classes + gsi::initialize_expressions (); +} class ProgressAdaptor : public tl::ProgressAdaptor diff --git a/src/buddies/src/bd/strmrun.cc b/src/buddies/src/bd/strmrun.cc index 130c75c10..74aa497dd 100644 --- a/src/buddies/src/bd/strmrun.cc +++ b/src/buddies/src/bd/strmrun.cc @@ -72,14 +72,6 @@ BD_PUBLIC int strmrun (int argc, char *argv[]) cmd.parse (argc, argv); - // initialize the GSI class system (Variant binding, Expression support) - // We have to do this now since plugins may register GSI classes and before the - // ruby interpreter, because it depends on a proper class system. - gsi::initialize (); - - // initialize the tl::Expression subsystem with GSI-bound classes - gsi::initialize_expressions (); - // create the ruby and python interpreter instances now. // Hint: we do this after load_plugin, because that way the plugins can register GSI classes and methods. // TODO: do this through some auto-registration From 08aacbd2e83053f8aebedaaa7a736881896c3084 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Fri, 13 Sep 2019 23:46:12 +0200 Subject: [PATCH 2/2] Provide tests to text buddy executables without framework --- src/buddies/unit_tests/buddies_main.cc | 51 +++++++++ src/buddies/unit_tests/unit_tests.pro | 8 +- testdata/buddies/buddies.rb | 142 +++++++++++++++++++++++++ testdata/buddies/out.gds | Bin 0 -> 160 bytes testdata/buddies/test1.gds | Bin 0 -> 170 bytes testdata/buddies/test2.gds | Bin 0 -> 170 bytes testdata/buddies/test2.rb | 3 + testdata/buddies/test_epilogue.rb | 36 +++++++ testdata/buddies/test_prologue.rb | 37 +++++++ 9 files changed, 273 insertions(+), 4 deletions(-) create mode 100644 src/buddies/unit_tests/buddies_main.cc create mode 100644 testdata/buddies/buddies.rb create mode 100644 testdata/buddies/out.gds create mode 100644 testdata/buddies/test1.gds create mode 100644 testdata/buddies/test2.gds create mode 100644 testdata/buddies/test2.rb create mode 100644 testdata/buddies/test_epilogue.rb create mode 100644 testdata/buddies/test_prologue.rb diff --git a/src/buddies/unit_tests/buddies_main.cc b/src/buddies/unit_tests/buddies_main.cc new file mode 100644 index 000000000..824901b8f --- /dev/null +++ b/src/buddies/unit_tests/buddies_main.cc @@ -0,0 +1,51 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2019 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +// NOTE: klayout_main_tests is actually a Ruby test which does all test automation +// The tests will also test Python capabilities, so Python is required too. + +#if defined(HAVE_RUBY) && defined(HAVE_PYTHON) + +#include "rba.h" +#include "gsiDecl.h" + +// On Windows, ruby.h is not compatible with windows.h which is included by utHead - at least not if +// windows.h is included before ruby.h ... +#include "tlUnitTest.h" + +void run_rubytest (tl::TestBase * /*_this*/, const std::string &fn) +{ + tl_assert (rba::RubyInterpreter::instance ()); + + std::string fp (tl::testsrc ()); + fp += "/testdata/buddies/"; + fp += fn; + rba::RubyInterpreter::instance ()->load_file (fp.c_str ()); +} + +#define RUBYTEST(n, file) \ + TEST(n) { run_rubytest(_this, file); } + +RUBYTEST (main, "buddies.rb") + +#endif + diff --git a/src/buddies/unit_tests/unit_tests.pro b/src/buddies/unit_tests/unit_tests.pro index 6e2e7825e..4f291cdaf 100644 --- a/src/buddies/unit_tests/unit_tests.pro +++ b/src/buddies/unit_tests/unit_tests.pro @@ -15,9 +15,9 @@ SOURCES = \ bdStrmcmpTests.cc \ bdStrmxorTests.cc \ bdStrmrunTests.cc \ + buddies_main.cc \ +INCLUDEPATH += $$BD_INC $$DB_INC $$TL_INC $$GSI_INC $$RBA_INC +DEPENDPATH += $$BD_INC $$DB_INC $$TL_INC $$GSI_INC $$RBA_INC -INCLUDEPATH += $$BD_INC $$DB_INC $$TL_INC $$GSI_INC -DEPENDPATH += $$BD_INC $$DB_INC $$TL_INC $$GSI_INC - -LIBS += -L$$DESTDIR_UT -lklayout_bd -lklayout_db -lklayout_tl -lklayout_gsi +LIBS += -L$$DESTDIR_UT -lklayout_bd -lklayout_db -lklayout_tl -lklayout_gsi -lklayout_rba diff --git a/testdata/buddies/buddies.rb b/testdata/buddies/buddies.rb new file mode 100644 index 000000000..46dcf6e5d --- /dev/null +++ b/testdata/buddies/buddies.rb @@ -0,0 +1,142 @@ +# encoding: UTF-8 + +# KLayout Layout Viewer +# Copyright (C) 2006-2019 Matthias Koefferlein +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end + +load("test_prologue.rb") + +# Tests for the buddy executables +# +# This tests actually runs inside a KLayout/unit_tests instance but +# only for providing the test automation. + +class Buddies_TestClass < TestBase + + def buddy_bin(name) + file = File.join(RBA::Application::instance.inst_path, name) + return file + end + + def test_basic + + # Basic - buddies can be called + %w(strm2cif strm2dxf strm2gds strm2gdstxt strm2oas strm2txt strmclip strmcmp strmrun strmxor).each do |bin| + version = bin + " " + `#{self.buddy_bin(bin)} --version` + assert_equal(version =~ /^#{bin} \d+\./, 0) + end + + end + + def test_converters + + %w(strm2cif strm2dxf strm2gds strm2gdstxt strm2oas strm2txt).each do |bin| + + puts "Testing #{bin} ..." + + out_file = File.join($ut_testtmp, "out") + if File.exists?(out_file) + File.unlink(out_file) + end + assert_equal(File.exists?(out_file), false) + + in_file = File.join(File.dirname(__FILE__), "test1.gds") + + log = bin + "\n" + `#{self.buddy_bin(bin)} #{in_file} #{out_file} 2>&1` + assert_equal(File.exists?(out_file), true) + assert_equal(log, bin + "\n") + + end + + end + + def test_strmxor + + out_file = File.join($ut_testtmp, "out") + if File.exists?(out_file) + File.unlink(out_file) + end + assert_equal(File.exists?(out_file), false) + + in_file1 = File.join(File.dirname(__FILE__), "test1.gds") + in_file2 = File.join(File.dirname(__FILE__), "test2.gds") + + log = "strmxor\n" + `#{self.buddy_bin("strmxor")} #{in_file1} #{in_file2} #{out_file} 2>&1` + assert_equal(File.exists?(out_file), true) + assert_equal(log, <<"END") +strmxor +Warning: Layer 1/0 is not present in second layout, but in first +Warning: Layer 2/0 is not present in first layout, but in second +Result summary (layers without differences are not shown): + + Layer Output Differences (shape count) + ------------------------------------------------------- + 1/0 - (no such layer in second layout) + 2/0 - (no such layer in first layout) + +END + + end + + def test_strmcmp + + in_file1 = File.join(File.dirname(__FILE__), "test1.gds") + in_file2 = File.join(File.dirname(__FILE__), "test2.gds") + + log = "strmcmp\n" + `#{self.buddy_bin("strmcmp")} #{in_file1} #{in_file2} 2>&1` + assert_equal(log, <<"END") +strmcmp +ERROR: Layer 1/0 is not present in layout b, but in a +ERROR: Layer 2/0 is not present in layout a, but in b +ERROR: Cell TOP1 is not present in layout b, but in a +ERROR: Cell TOP2 is not present in layout a, but in b +ERROR: Layouts differ +END + + end + + def test_strmclip + + out_file = File.join($ut_testtmp, "out") + if File.exists?(out_file) + File.unlink(out_file) + end + assert_equal(File.exists?(out_file), false) + + in_file = File.join(File.dirname(__FILE__), "test1.gds") + + log = "strmclip\n" + `#{self.buddy_bin("strmclip")} #{in_file} #{out_file} 2>&1` + assert_equal(File.exists?(out_file), true) + assert_equal(log, "strmclip\n") + + end + + def test_strmrun + + in_file = File.join(File.dirname(__FILE__), "test2.rb") + + log = "strmrun\n" + `#{self.buddy_bin("strmrun")} #{in_file} 2>&1` + assert_equal(log, "strmrun\ntest2\n") + + end + +end + +load("test_epilogue.rb") diff --git a/testdata/buddies/out.gds b/testdata/buddies/out.gds new file mode 100644 index 0000000000000000000000000000000000000000..8a7c850d569d14076117f532d3a3362847790671 GIT binary patch literal 160 zcmZQzV_;&6V31*CVt>rQ$-v7X4#ZN(Yz7V{HXlzX1_lvkRy)T|bMIrzKUli#&|fe+ pDuh9X6}LVCHa2G;&wv0|m-rC>00ssYb_Tra`4H-zA*xwe7yx8o7QFxf literal 0 HcmV?d00001 diff --git a/testdata/buddies/test1.gds b/testdata/buddies/test1.gds new file mode 100644 index 0000000000000000000000000000000000000000..7cfbe49107ec4eeb1ce3efaaa5664e155cd109d1 GIT binary patch literal 170 zcmZQzV_;&6V31*CVt>fM!ywHd$RNaEg3M;%U}E#}bYfr-VP>^+>@@d2w)}&o%MSeo zv!g;7WLWX&V`B^P4=`k4;b353<7HxCWMJcCVqjp<5nu+ANI>3!fdLsKNwEkrFtD%# HF$)6#f9ny) literal 0 HcmV?d00001 diff --git a/testdata/buddies/test2.gds b/testdata/buddies/test2.gds new file mode 100644 index 0000000000000000000000000000000000000000..93410146069c624053808507794a9f405f81030e GIT binary patch literal 170 zcmZQzV_;&6V31*CVt>fM!ywHd$RNxhjLc@>U}E#}bYfr-VP>^+>@@d2w)}&o%MSeo zv!g;7WLWX&V`B^P4=`e2;b353<7HxCVqoKAVqjp<5nu+ANI>3!fdLsKNwEkrFtD%# HF$)6#M*9&- literal 0 HcmV?d00001 diff --git a/testdata/buddies/test2.rb b/testdata/buddies/test2.rb new file mode 100644 index 000000000..b59aa43c1 --- /dev/null +++ b/testdata/buddies/test2.rb @@ -0,0 +1,3 @@ + +puts "test2" + diff --git a/testdata/buddies/test_epilogue.rb b/testdata/buddies/test_epilogue.rb new file mode 100644 index 000000000..f0f5bacc3 --- /dev/null +++ b/testdata/buddies/test_epilogue.rb @@ -0,0 +1,36 @@ + +# In the test environment, we cannot make sure that we destroy the ruby interpreter before the RBA +# environment is shut down. Therefore we must release all RBA objects by explicitly calling the GC +# and start the test suite manually. + +err = 0 +any = nil +repeat = (ENV["TESTREPEAT"] || "1").to_i + +class MyTestRunner < Test::Unit::UI::Console::TestRunner + def initialize(suite, *args) + super(suite, *args) + end + def test_started(name) + super + end +end + +Object.constants.each do |c| + if c.to_s =~ /_TestClass$/ + repeat.times do + r = MyTestRunner::new(Object.const_get(c)).start + err += r.error_count + r.failure_count + end + any = true + end +end + +if !any + raise("No test class defined (any ending with _TestClass)") +end + +if err > 0 + raise("Tests failed (#{err} Errors + Failures)") +end + diff --git a/testdata/buddies/test_prologue.rb b/testdata/buddies/test_prologue.rb new file mode 100644 index 000000000..4dcd70124 --- /dev/null +++ b/testdata/buddies/test_prologue.rb @@ -0,0 +1,37 @@ + +# in MSVC environment: +if ENV["RUBY"] + ruby_libs = "#{ENV["RUBY"]}/lib/ruby/#{RUBY_VERSION}" + if !$:.member?(ruby_libs) + $:.push(ruby_libs) + end +end + +# Set this to true to disable some tests involving exceptions +$leak_check = ENV["TEST_LEAK_CHECK"] + +# Fetch location of source files and the temp files +$ut_testsrc = ENV["TESTSRC"] || raise("Environment variable $TESTSRC not set") +$ut_testtmp = ENV["TESTTMP_WITH_NAME"] || ENV["TESTTMP"] || raise("Environment variable $TESTTMP not set") + +# Pull packages from vendor drop-in +vendor = File.join($ut_testsrc, "testdata", "vendor", "ruby") +if !$:.member?(vendor) + $:.unshift(vendor) +end + +# Require Test::Unit +require 'test/unit/ui/console/testrunner' + +# TestBase is an alias for "TestCase" +Object.const_defined?(:TestBase) && Object.send(:remove_const, :TestBase) +TestBase = Test::Unit::TestCase + +# undefine existing classes + +Object.constants.each do |c| + if c.to_s =~ /_TestClass$/ + Object.send(:remove_const, c) + end +end +