Browse Source

use Google C++ Testing Framework for libapt tests

My commit 45df0ad2 from 26. Nov 2009 had a little remark:
"The commit also includes a very very simple testapp."
This was never intended to be permanent, but as usually…

The commit adds the needed make magic to compile gtest statically
as it is required and links it against a small runner. All previous
testcase binaries are reimplemented in gtest and combined in this
runner. While most code is a 1:1 translation some had to be rewritten
like compareversion_test.cc, but the coverage remains the same.
David Kalnischkies 10 years ago
parent
commit
f00832cc27

+ 1 - 1
debian/control

@@ -9,7 +9,7 @@ Build-Depends: dpkg-dev (>= 1.15.8), debhelper (>= 8.1.3~), libdb-dev,
  gettext (>= 0.12), libcurl4-gnutls-dev (>= 7.19.4~),
  zlib1g-dev, libbz2-dev, liblzma-dev,
  xsltproc, docbook-xsl, docbook-xml, po4a (>= 0.34-2),
- autotools-dev, autoconf, automake
+ autotools-dev, autoconf, automake, libgtest-dev
 Build-Depends-Indep: doxygen, debiandoc-sgml, graphviz
 Build-Conflicts: autoconf2.13, automake1.4
 Vcs-Git: git://anonscm.debian.org/apt/apt.git

+ 0 - 126
test/libapt/assert.h

@@ -1,126 +0,0 @@
-#include <iostream>
-#include <cstdlib>
-
-#include <apt-pkg/macros.h>
-#include <apt-pkg/error.h>
-
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic push
-	#pragma GCC diagnostic ignored "-Wmissing-declarations"
-#endif
-
-#define equals(x,y) assertEquals(y, x, __LINE__)
-#define equalsNot(x,y) assertEqualsNot(y, x, __LINE__)
-
-template < typename X, typename Y >
-APT_NORETURN void OutputAssertEqual(X expect, char const* compare, Y get, unsigned long const &line) {
-	std::cerr << "Test FAILED: »" << expect << "« " << compare << " »" << get << "« at line " << line << std::endl;
-	_error->DumpErrors(std::cerr);
-	std::exit(EXIT_FAILURE);
-}
-
-template < typename X, typename Y >
-void assertEquals(X expect, Y get, unsigned long const &line) {
-	if (expect == get)
-		return;
-	OutputAssertEqual(expect, "==", get, line);
-}
-
-template < typename X, typename Y >
-void assertEqualsNot(X expect, Y get, unsigned long const &line) {
-	if (expect != get)
-		return;
-	OutputAssertEqual(expect, "!=", get, line);
-}
-
-void assertEquals(unsigned int const &expect, int const &get, unsigned long const &line) {
-	if (get < 0)
-		OutputAssertEqual(expect, "==", get, line);
-	assertEquals<unsigned int const&, unsigned int const&>(expect, get, line);
-}
-
-void assertEquals(int const &expect, unsigned int const &get, unsigned long const &line) {
-	if (expect < 0)
-		OutputAssertEqual(expect, "==", get, line);
-	assertEquals<unsigned int const&, unsigned int const&>(expect, get, line);
-}
-
-void assertEquals(unsigned long const &expect, int const &get, unsigned long const &line) {
-	if (get < 0)
-		OutputAssertEqual(expect, "==", get, line);
-	assertEquals<unsigned long const&, unsigned long const&>(expect, get, line);
-}
-
-void assertEquals(int const &expect, unsigned long const &get, unsigned long const &line) {
-	if (expect < 0)
-		OutputAssertEqual(expect, "==", get, line);
-	assertEquals<unsigned long const&, unsigned long const&>(expect, get, line);
-}
-
-
-#define equalsOr2(x,y,z) assertEqualsOr2(y, z, x, __LINE__)
-
-template < typename X, typename Y >
-void OutputAssertEqualOr2(X expect1, X expect2, char const* compare, Y get, unsigned long const &line) {
-	std::cerr << "Test FAILED: »" << expect1 << "« or »" << expect2 << "« " << compare << " »" << get << "« at line " << line << std::endl;
-}
-
-template < typename X, typename Y >
-void assertEqualsOr2(X expect1, X expect2, Y get, unsigned long const &line) {
-	if (expect1 == get || expect2 == get)
-		return;
-	OutputAssertEqualOr2(expect1, expect2, "==", get, line);
-}
-
-void assertEqualsOr2(unsigned int const &expect1, unsigned int const &expect2, int const &get, unsigned long const &line) {
-	if (get < 0)
-		OutputAssertEqualOr2(expect1, expect2, "==", get, line);
-	assertEqualsOr2<unsigned int const&, unsigned int const&>(expect1, expect2, get, line);
-}
-
-void assertEqualsOr2(int const &expect1, int const &expect2, unsigned int const &get, unsigned long const &line) {
-	if (expect1 < 0 && expect2 < 0)
-		OutputAssertEqualOr2(expect1, expect2, "==", get, line);
-	assertEqualsOr2<unsigned int const&, unsigned int const&>(expect1, expect2, get, line);
-}
-
-
-#define equalsOr3(w,x,y,z) assertEqualsOr3(x, y, z, w, __LINE__)
-
-template < typename X, typename Y >
-void OutputAssertEqualOr3(X expect1, X expect2, X expect3, char const* compare, Y get, unsigned long const &line) {
-	std::cerr << "Test FAILED: »" << expect1 << "« or »" << expect2 << "« or »" << expect3 << "« " << compare << " »" << get << "« at line " << line << std::endl;
-}
-
-template < typename X, typename Y >
-void assertEqualsOr3(X expect1, X expect2, X expect3, Y get, unsigned long const &line) {
-	if (expect1 == get || expect2 == get || expect3 == get)
-		return;
-	OutputAssertEqualOr3(expect1, expect2, expect3, "==", get, line);
-}
-
-#define equalsOr4(v,w,x,y,z) assertEqualsOr4(w, x, y, z, v, __LINE__)
-
-template < typename X, typename Y >
-void OutputAssertEqualOr4(X expect1, X expect2, X expect3, X expect4, char const* compare, Y get, unsigned long const &line) {
-	std::cerr << "Test FAILED: »" << expect1 << "« or »" << expect2 << "« or »" << expect3 << "« or »" << expect4 << "« " << compare << " »" << get << "« at line " << line << std::endl;
-}
-
-template < typename X, typename Y >
-void assertEqualsOr4(X expect1, X expect2, X expect3, X expect4, Y get, unsigned long const &line) {
-	if (expect1 == get || expect2 == get || expect3 == get || expect4 == get)
-		return;
-	OutputAssertEqualOr4(expect1, expect2, expect3, expect4, "==", get, line);
-}
-
-// simple helper to quickly output a vectors
-template < typename X >
-void dumpVector(X vec) {
-	for (typename X::const_iterator v = vec.begin();
-	     v != vec.end(); ++v)
-		std::cout << *v << std::endl;
-}
-
-#if __GNUC__ >= 4
-	#pragma GCC diagnostic pop
-#endif

File diff suppressed because it is too large
+ 114 - 0
test/libapt/cdrom_test.cc


+ 0 - 26
test/libapt/cdromfindmountpointfordevice_test.cc

@@ -1,26 +0,0 @@
-#include <config.h>
-
-#include <apt-pkg/cdromutl.h>
-#include <apt-pkg/configuration.h>
-
-#include <string>
-#include <vector>
-
-#include "assert.h"
-
-int main(int argc, char const *argv[]) {
-	if (argc != 2) {
-		std::cout << "One parameter expected - given " << argc << std::endl;
-		return 100;
-	}
-
-	_config->Set("Dir::state::Mountpoints", argv[1]);
-	equals("/", FindMountPointForDevice("rootfs"));
-	equals("/", FindMountPointForDevice("/dev/disk/by-uuid/fadcbc52-6284-4874-aaaa-dcee1f05fe21"));
-	equals("/sys", FindMountPointForDevice("sysfs"));
-	equals("/sys0", FindMountPointForDevice("sysfs0"));
-	equals("/boot/efi", FindMountPointForDevice("/dev/sda1"));
-	equals("/tmp", FindMountPointForDevice("tmpfs"));
-
-	return 0;
-}

+ 100 - 69
test/libapt/cdromfindpackages_test.cc

@@ -2,6 +2,7 @@
 
 #include <apt-pkg/cdrom.h>
 #include <apt-pkg/error.h>
+#include <apt-pkg/fileutl.h>
 
 #include <algorithm>
 #include <string>
@@ -9,82 +10,112 @@
 #include <stddef.h>
 #include <iostream>
 
-#include "assert.h"
+#include <gtest/gtest.h>
+
+#include "file-helpers.h"
 
 class Cdrom : public pkgCdrom {
-	public:
-	bool FindPackages(std::string const &CD,
-			  std::vector<std::string> &List,
-			  std::vector<std::string> &SList,
-			  std::vector<std::string> &SigList,
-			  std::vector<std::string> &TransList,
-			  std::string &InfoDir) {
-		bool const result = pkgCdrom::FindPackages(CD, List, SList, SigList, TransList, InfoDir, NULL, 0);
-		std::sort(List.begin(), List.end());
-		std::sort(SList.begin(), SList.end());
-		std::sort(SigList.begin(), SigList.end());
-		std::sort(TransList.begin(), TransList.end());
-		return result;
-	}
+   public:
+      bool FindPackages(std::string const &CD,
+	    std::vector<std::string> &List,
+	    std::vector<std::string> &SList,
+	    std::vector<std::string> &SigList,
+	    std::vector<std::string> &TransList,
+	    std::string &InfoDir) {
+	 std::string const startdir = SafeGetCWD();
+	 EXPECT_FALSE(startdir.empty());
+	 bool const result = pkgCdrom::FindPackages(CD, List, SList, SigList, TransList, InfoDir, NULL, 0);
+	 std::sort(List.begin(), List.end());
+	 std::sort(SList.begin(), SList.end());
+	 std::sort(SigList.begin(), SigList.end());
+	 std::sort(TransList.begin(), TransList.end());
+	 EXPECT_EQ(0, chdir(startdir.c_str()));
+	 return result;
+      }
 
-	bool DropRepeats(std::vector<std::string> &List, char const *Name) {
-		return pkgCdrom::DropRepeats(List, Name);
-	}
+      using pkgCdrom::DropRepeats;
 };
 
-int main(int argc, char const *argv[]) {
-	if (argc != 2) {
-		std::cout << "One parameter expected - given " << argc << std::endl;
-		return 100;
-	}
+TEST(CDROMTest,FindPackages)
+{
+   std::string path;
+   createTemporaryDirectory("findpackage", path);
+
+   createDirectory(path, ".disk");
+   createDirectory(path, "pool");
+   createDirectory(path, "dists/stable/main/binary-i386");
+   createDirectory(path, "dists/stable/main/source");
+   createDirectory(path, "dists/stable/contrib/binary-amd64");
+   createDirectory(path, "dists/stable/contrib/binary-all");
+   createDirectory(path, "dists/unstable/main/binary-i386");
+   createDirectory(path, "dists/unstable/main/i18n");
+   createDirectory(path, "dists/unstable/main/source");
+   createDirectory(path, "dists/broken/non-free/source");
+   createFile(path, "dists/broken/.aptignr");
+   createFile(path, "dists/stable/main/binary-i386/Packages");
+   createFile(path, "dists/stable/main/binary-i386/Packages.bz2");
+   createFile(path, "dists/stable/main/source/Sources.xz");
+   createFile(path, "dists/stable/contrib/binary-amd64/Packages");
+   createFile(path, "dists/stable/contrib/binary-amd64/Packages.gz");
+   createFile(path, "dists/stable/contrib/binary-all/Packages");
+   createFile(path, "dists/unstable/main/binary-i386/Packages.xz");
+   createFile(path, "dists/unstable/main/binary-i386/Packages.lzma");
+   createFile(path, "dists/unstable/main/i18n/Translation-en");
+   createFile(path, "dists/unstable/main/i18n/Translation-de.bz2");
+   createFile(path, "dists/unstable/main/source/Sources.xz");
+   createFile(path, "dists/broken/non-free/source/Sources.gz");
+   createFile(path, "dists/stable/Release.gpg");
+   createFile(path, "dists/stable/Release");
+   createFile(path, "dists/unstable/InRelease");
+   createFile(path, "dists/broken/Release.gpg");
+   createLink(path, "dists/unstable", "dists/sid");
 
-	Cdrom cd;
-	std::vector<std::string> Packages, Sources, Signatur, Translation;
-	std::string InfoDir;
-	std::string path = argv[1];
-	equals(true, cd.FindPackages(path, Packages, Sources, Signatur, Translation, InfoDir));
-	equals(4, Packages.size());
-	equals(path + "/dists/sid/main/binary-i386/", Packages[0]);
-	equals(path + "/dists/stable/contrib/binary-amd64/", Packages[1]);
-	equals(path + "/dists/stable/main/binary-i386/", Packages[2]);
-	equals(path + "/dists/unstable/main/binary-i386/", Packages[3]);
-	equals(3, Sources.size());
-	equals(path + "/dists/sid/main/source/", Sources[0]);
-	equals(path + "/dists/stable/main/source/", Sources[1]);
-	equals(path + "/dists/unstable/main/source/", Sources[2]);
-	equals(3, Signatur.size());
-	equals(path + "/dists/sid/", Signatur[0]);
-	equals(path + "/dists/stable/", Signatur[1]);
-	equals(path + "/dists/unstable/", Signatur[2]);
-	equals(4, Translation.size());
-	equals(path + "/dists/sid/main/i18n/Translation-de", Translation[0]);
-	equals(path + "/dists/sid/main/i18n/Translation-en", Translation[1]);
-	equals(path + "/dists/unstable/main/i18n/Translation-de", Translation[2]);
-	equals(path + "/dists/unstable/main/i18n/Translation-en", Translation[3]);
-	equals(path + "/.disk/", InfoDir);
+   Cdrom cd;
+   std::vector<std::string> Packages, Sources, Signatur, Translation;
+   std::string InfoDir;
+   EXPECT_TRUE(cd.FindPackages(path, Packages, Sources, Signatur, Translation, InfoDir));
+   EXPECT_EQ(4, Packages.size());
+   EXPECT_EQ(path + "/dists/sid/main/binary-i386/", Packages[0]);
+   EXPECT_EQ(path + "/dists/stable/contrib/binary-amd64/", Packages[1]);
+   EXPECT_EQ(path + "/dists/stable/main/binary-i386/", Packages[2]);
+   EXPECT_EQ(path + "/dists/unstable/main/binary-i386/", Packages[3]);
+   EXPECT_EQ(3, Sources.size());
+   EXPECT_EQ(path + "/dists/sid/main/source/", Sources[0]);
+   EXPECT_EQ(path + "/dists/stable/main/source/", Sources[1]);
+   EXPECT_EQ(path + "/dists/unstable/main/source/", Sources[2]);
+   EXPECT_EQ(3, Signatur.size());
+   EXPECT_EQ(path + "/dists/sid/", Signatur[0]);
+   EXPECT_EQ(path + "/dists/stable/", Signatur[1]);
+   EXPECT_EQ(path + "/dists/unstable/", Signatur[2]);
+   EXPECT_EQ(4, Translation.size());
+   EXPECT_EQ(path + "/dists/sid/main/i18n/Translation-de", Translation[0]);
+   EXPECT_EQ(path + "/dists/sid/main/i18n/Translation-en", Translation[1]);
+   EXPECT_EQ(path + "/dists/unstable/main/i18n/Translation-de", Translation[2]);
+   EXPECT_EQ(path + "/dists/unstable/main/i18n/Translation-en", Translation[3]);
+   EXPECT_EQ(path + "/.disk/", InfoDir);
 
-	cd.DropRepeats(Packages, "Packages");
-	cd.DropRepeats(Sources, "Sources");
-	_error->PushToStack();
-	cd.DropRepeats(Signatur, "InRelease");
-	cd.DropRepeats(Signatur, "Release.gpg");
-	_error->RevertToStack();
-	_error->DumpErrors();
-	cd.DropRepeats(Translation, "");
+   cd.DropRepeats(Packages, "Packages");
+   cd.DropRepeats(Sources, "Sources");
+   _error->PushToStack();
+   cd.DropRepeats(Signatur, "InRelease");
+   cd.DropRepeats(Signatur, "Release.gpg");
+   _error->RevertToStack();
+   _error->DumpErrors();
+   cd.DropRepeats(Translation, "");
 
-	equals(3, Packages.size());
-	equals(path + "/dists/stable/contrib/binary-amd64/", Packages[0]);
-	equals(path + "/dists/stable/main/binary-i386/", Packages[1]);
-	equals(path + "/dists/unstable/main/binary-i386/", Packages[2]);
-	equals(2, Sources.size());
-	equals(path + "/dists/stable/main/source/", Sources[0]);
-	equals(path + "/dists/unstable/main/source/", Sources[1]);
-	equals(2, Signatur.size());
-	equals(path + "/dists/stable/", Signatur[0]);
-	equals(path + "/dists/unstable/", Signatur[1]);
-	equals(2, Translation.size());
-	equals(path + "/dists/unstable/main/i18n/Translation-de", Translation[0]);
-	equals(path + "/dists/unstable/main/i18n/Translation-en", Translation[1]);
+   EXPECT_EQ(3, Packages.size());
+   EXPECT_EQ(path + "/dists/stable/contrib/binary-amd64/", Packages[0]);
+   EXPECT_EQ(path + "/dists/stable/main/binary-i386/", Packages[1]);
+   EXPECT_EQ(path + "/dists/unstable/main/binary-i386/", Packages[2]);
+   EXPECT_EQ(2, Sources.size());
+   EXPECT_EQ(path + "/dists/stable/main/source/", Sources[0]);
+   EXPECT_EQ(path + "/dists/unstable/main/source/", Sources[1]);
+   EXPECT_EQ(2, Signatur.size());
+   EXPECT_EQ(path + "/dists/stable/", Signatur[0]);
+   EXPECT_EQ(path + "/dists/unstable/", Signatur[1]);
+   EXPECT_EQ(2, Translation.size());
+   EXPECT_EQ(path + "/dists/unstable/main/i18n/Translation-de", Translation[0]);
+   EXPECT_EQ(path + "/dists/unstable/main/i18n/Translation-en", Translation[1]);
 
-	return 0;
+   removeDirectory(path);
 }

+ 0 - 86
test/libapt/cdromreducesourcelist_test.cc

@@ -1,86 +0,0 @@
-#include <config.h>
-
-#include <apt-pkg/cdrom.h>
-
-#include <string>
-#include <vector>
-
-#include "assert.h"
-
-class Cdrom : public pkgCdrom {
-public:
-   std::vector<std::string> ReduceSourcelist(std::string CD,std::vector<std::string> List) {
-      pkgCdrom::ReduceSourcelist(CD, List);
-      return List;
-   }
-};
-
-int main() {
-   Cdrom cd;
-   std::vector<std::string> List;
-   std::string CD("/media/cdrom/");
-
-   std::vector<std::string> R = cd.ReduceSourcelist(CD, List);
-   equals(R.empty(), true);
-
-   List.push_back(" wheezy main");
-   R = cd.ReduceSourcelist(CD, List);
-   equals(R.size(), 1);
-   equals(R[0], " wheezy main");
-
-   List.push_back(" wheezy main");
-   R = cd.ReduceSourcelist(CD, List);
-   equals(R.size(), 1);
-   equals(R[0], " wheezy main");
-
-   List.push_back(" wheezy contrib");
-   R = cd.ReduceSourcelist(CD, List);
-   equals(R.size(), 1);
-   equals(R[0], " wheezy contrib main");
-
-   List.push_back(" wheezy-update contrib");
-   R = cd.ReduceSourcelist(CD, List);
-   equals(R.size(), 2);
-   equals(R[0], " wheezy contrib main");
-   equals(R[1], " wheezy-update contrib");
-
-   List.push_back(" wheezy-update contrib");
-   R = cd.ReduceSourcelist(CD, List);
-   equals(R.size(), 2);
-   equals(R[0], " wheezy contrib main");
-   equals(R[1], " wheezy-update contrib");
-
-   List.push_back(" wheezy-update non-free");
-   R = cd.ReduceSourcelist(CD, List);
-   equals(R.size(), 2);
-   equals(R[0], " wheezy contrib main");
-   equals(R[1], " wheezy-update contrib non-free");
-
-   List.push_back(" wheezy-update main");
-   R = cd.ReduceSourcelist(CD, List);
-   equals(R.size(), 2);
-   equals(R[0], " wheezy contrib main");
-   equals(R[1], " wheezy-update contrib main non-free");
-
-   List.push_back(" wheezy non-free");
-   R = cd.ReduceSourcelist(CD, List);
-   equals(R.size(), 2);
-   equals(R[0], " wheezy contrib main non-free");
-   equals(R[1], " wheezy-update contrib main non-free");
-
-   List.push_back(" sid main");
-   R = cd.ReduceSourcelist(CD, List);
-   equals(R.size(), 3);
-   equals(R[0], " sid main");
-   equals(R[1], " wheezy contrib main non-free");
-   equals(R[2], " wheezy-update contrib main non-free");
-
-   List.push_back(" sid main-reduce");
-   R = cd.ReduceSourcelist(CD, List);
-   equals(R.size(), 3);
-   equals(R[0], " sid main main-reduce");
-   equals(R[1], " wheezy contrib main non-free");
-   equals(R[2], " wheezy-update contrib main non-free");
-
-   return 0;
-}

+ 38 - 15
test/libapt/commandline_test.cc

@@ -3,33 +3,56 @@
 #include <apt-pkg/cmndline.h>
 #include <apt-pkg/configuration.h>
 
-#include "assert.h"
-
-int main()
+#include <gtest/gtest.h>
+
+class CLT: public CommandLine {
+   public:
+      std::string static AsString(const char * const * const argv,
+	    unsigned int const argc) {
+	 std::string const static conf = "Commandline::AsString";
+	 _config->Clear(conf);
+	 SaveInConfig(argc, argv);
+	 return _config->Find(conf);
+      }
+};
+
+#define EXPECT_CMD(x, ...) { const char * const argv[] = { __VA_ARGS__ }; EXPECT_EQ(x, CLT::AsString(argv, sizeof(argv)/sizeof(argv[0]))); }
+
+TEST(CommandLineTest,SaveInConfig)
+{
+   EXPECT_CMD("apt-get install -sf",
+	 "apt-get", "install", "-sf");
+   EXPECT_CMD("apt-cache -s apt -so Debug::test=Test",
+	 "apt-cache", "-s", "apt", "-so", "Debug::test=Test");
+   EXPECT_CMD("apt-cache -s apt -so Debug::test=\"Das ist ein Test\"",
+	 "apt-cache", "-s", "apt", "-so", "Debug::test=Das ist ein Test");
+   EXPECT_CMD("apt-cache -s apt --hallo test=1.0",
+	 "apt-cache", "-s", "apt", "--hallo", "test=1.0");
+}
+TEST(CommandLineTest,Parsing)
 {
    CommandLine::Args Args[] = {
       { 't', 0, "Test::Worked", 0 },
       { 'z', "zero", "Test::Zero", 0 },
       {0,0,0,0}
    };
-   CommandLine CmdL(Args,_config);
+   ::Configuration c;
+   CommandLine CmdL(Args, &c);
 
    char const * argv[] = { "test", "--zero", "-t" };
    CmdL.Parse(3 , argv);
-   equals(true, _config->FindB("Test::Worked", false));
-   equals(true, _config->FindB("Test::Zero", false));
+   EXPECT_TRUE(c.FindB("Test::Worked", false));
+   EXPECT_TRUE(c.FindB("Test::Zero", false));
 
-   _config->Clear("Test");
-   equals(false, _config->FindB("Test::Worked", false));
-   equals(false, _config->FindB("Test::Zero", false));
+   c.Clear("Test");
+   EXPECT_FALSE(c.FindB("Test::Worked", false));
+   EXPECT_FALSE(c.FindB("Test::Zero", false));
 
-   _config->Set("Test::Zero", true);
-   equals(true, _config->FindB("Test::Zero", false));
+   c.Set("Test::Zero", true);
+   EXPECT_TRUE(c.FindB("Test::Zero", false));
 
    char const * argv2[] = { "test", "--no-zero", "-t" };
    CmdL.Parse(3 , argv2);
-   equals(true, _config->FindB("Test::Worked", false));
-   equals(false, _config->FindB("Test::Zero", false));
-
-   return 0;
+   EXPECT_TRUE(c.FindB("Test::Worked", false));
+   EXPECT_FALSE(c.FindB("Test::Zero", false));
 }

+ 0 - 41
test/libapt/commandlineasstring_test.cc

@@ -1,41 +0,0 @@
-#include <config.h>
-
-#include <apt-pkg/cmndline.h>
-#include <apt-pkg/configuration.h>
-
-#include <string>
-
-#include "assert.h"
-
-class CLT: public CommandLine {
-
-	public:
-	std::string static AsString(const char * const * const argv,
-				    unsigned int const argc) {
-		std::string const static conf = "Commandline::AsString";
-		_config->Clear(conf);
-		SaveInConfig(argc, argv);
-		return _config->Find(conf);
-	}
-};
-
-#define CMD(y,z) equals(CLT::AsString(argv, y), z);
-
-int main() {
-	{
-		const char* const argv[] = {"apt-get", "install", "-sf"};
-		CMD(3, "apt-get install -sf");
-	}
-	{
-		const char* const argv[] = {"apt-cache", "-s", "apt", "-so", "Debug::test=Test"};
-		CMD(5, "apt-cache -s apt -so Debug::test=Test");
-	}
-	{
-		const char* const argv[] = {"apt-cache", "-s", "apt", "-so", "Debug::test=Das ist ein Test"};
-		CMD(5, "apt-cache -s apt -so Debug::test=\"Das ist ein Test\"");
-	}
-	{
-		const char* const argv[] = {"apt-cache", "-s", "apt", "--hallo", "test=1.0"};
-		CMD(5, "apt-cache -s apt --hallo test=1.0");
-	}
-}

+ 120 - 65
test/libapt/compareversion_test.cc

@@ -28,9 +28,11 @@
 #include <unistd.h>
 #include <sys/wait.h>
 
+#include <gtest/gtest.h>
+
 using namespace std;
 
-static bool callDPkg(const char *val, const char *ref, const char &op) {
+static bool callDPKG(const char *val, const char *ref, const char &op) {
    pid_t Process = ExecFork();
    if (Process == 0)
    {
@@ -49,77 +51,130 @@ static bool callDPkg(const char *val, const char *ref, const char &op) {
    return WIFEXITED(Ret) == true && WEXITSTATUS(Ret) == 0;
 }
 
-static void assertVersion(int const &CurLine, string const &A, string const &B, int const &Expected) {
-   int Res = debVS.CmpVersion(A.c_str(), B.c_str());
-   bool const dpkg = callDPkg(A.c_str(),B.c_str(), Expected);
-   Res = (Res < 0) ? -1 : ( (Res > 0) ? 1 : Res);
 
-   if (Res != Expected)
-      _error->Error("Comparison failed on line %u. '%s' '%s' '%s' %i != %i",CurLine,A.c_str(),((Expected == 1) ? "<<" : ( (Expected == 0) ? "=" : ">>")) ,B.c_str(),Res,Expected);
-   if (dpkg == false)
-      _error->Error("DPkg differ with line: %u. '%s' '%s' '%s' == false",CurLine,A.c_str(),((Expected == 1) ? "<<" : ( (Expected == 0) ? "=" : ">>")),B.c_str());
+#define EXPECT_VERSION_PART(A, compare, B) \
+{ \
+   int Res = debVS.CmpVersion(A, B); \
+   Res = (Res < 0) ? -1 : ( (Res > 0) ? 1 : Res); \
+   EXPECT_EQ(compare, Res) << "APT: A: »" << A << "« B: »" << B << "«"; \
+   EXPECT_PRED3(callDPKG, A, B, compare); \
 }
+#define EXPECT_VERSION(A, compare, B) \
+   EXPECT_VERSION_PART(A, compare, B); \
+   EXPECT_VERSION_PART(B, compare * -1, A)
+
+// History-Remark: The versions used to be specified in a versions.lst file
+
+enum CompareVersionType { LESS = -1, GREATER = 1, EQUAL = 0 };
 
-static bool RunTest(const char *File)
+TEST(CompareVersionTest,Basic)
 {
-   if (FileExists(File) == false)
-      return _error->Error("Versiontestfile %s doesn't exist!", File);
+   EXPECT_VERSION("7.6p2-4", GREATER, "7.6-0");
+   EXPECT_VERSION("1.0.3-3", GREATER, "1.0-1");
+   EXPECT_VERSION("1.3", GREATER, "1.2.2-2");
+   EXPECT_VERSION("1.3", GREATER, "1.2.2");
 
-   ifstream F(File,ios::in);
-   if (!F != 0)
-      return false;
+   /* disabled as dpkg doesn't like them… (versions have to start with a number)
+   EXPECT_VERSION("-", LESS, ".");
+   EXPECT_VERSION("p", LESS, "-");
+   EXPECT_VERSION("a", LESS, "-");
+   EXPECT_VERSION("z", LESS, "-");
+   EXPECT_VERSION("a", LESS, ".");
+   EXPECT_VERSION("z", LESS, ".");
+   // */
 
-   char Buffer[300];
-   int CurLine = 0;
-   
-   while (1)
-   {
-      F.getline(Buffer,sizeof(Buffer));
-      CurLine++;
-      if (F.eof() != 0)
-	 return true;
-      if (!F != 0)
-	 return _error->Error("Line %u in %s is too long",CurLine,File);
-
-      // Comment
-      if (Buffer[0] == '#' || Buffer[0] == 0)
-	 continue;
-      
-      // First version
-      char *I;
-      char *Start = Buffer;
-      for (I = Buffer; *I != 0 && *I != ' '; I++);
-      string A(Start, I - Start);
-
-      if (*I == 0)
-	 return _error->Error("Invalid line %u",CurLine);
-      
-      // Second version
-      I++;
-      Start = I;
-      for (I = Start; *I != 0 && *I != ' '; I++);
-      string B(Start,I - Start);
-      
-      if (*I == 0 || I[1] == 0)
-	 return _error->Error("Invalid line %u",CurLine);
-      
-      // Result
-      I++;
-      int const Expected = atoi(I);
-      assertVersion(CurLine, A, B, Expected);
-      // Check the reverse as well
-      assertVersion(CurLine, B, A, Expected*-1);
-   }
+   /* disabled as dpkg doesn't like them… (versions have to start with a number)
+   EXPECT_VERSION("III-alpha9.8", LESS, "III-alpha9.8-1.5");
+   // */
+
+   // Test some properties of text strings
+   EXPECT_VERSION("0-pre", EQUAL, "0-pre");
+   EXPECT_VERSION("0-pre", LESS, "0-pree");
+
+   EXPECT_VERSION("1.1.6r2-2", GREATER, "1.1.6r-1");
+   EXPECT_VERSION("2.6b2-1", GREATER, "2.6b-2");
+
+   EXPECT_VERSION("98.1p5-1", LESS, "98.1-pre2-b6-2");
+   EXPECT_VERSION("0.4a6-2", GREATER, "0.4-1");
+
+   EXPECT_VERSION("1:3.0.5-2", LESS, "1:3.0.5.1");
 }
+TEST(CompareVersionTest,Epochs)
+{
+   EXPECT_VERSION("1:0.4", GREATER, "10.3");
+   EXPECT_VERSION("1:1.25-4", LESS, "1:1.25-8");
+   EXPECT_VERSION("0:1.18.36", EQUAL, "1.18.36");
+
+   EXPECT_VERSION("1.18.36", GREATER, "1.18.35");
+   EXPECT_VERSION("0:1.18.36", GREATER, "1.18.35");
+}
+TEST(CompareVersionTest,Strangeness)
+{
+   // Funky, but allowed, characters in upstream version
+   EXPECT_VERSION("9:1.18.36:5.4-20", LESS, "10:0.5.1-22");
+   EXPECT_VERSION("9:1.18.36:5.4-20", LESS, "9:1.18.36:5.5-1");
+   EXPECT_VERSION("9:1.18.36:5.4-20", LESS, " 9:1.18.37:4.3-22");
+   EXPECT_VERSION("1.18.36-0.17.35-18", GREATER, "1.18.36-19");
+
+   // Junk
+   EXPECT_VERSION("1:1.2.13-3", LESS, "1:1.2.13-3.1");
+   EXPECT_VERSION("2.0.7pre1-4", LESS, "2.0.7r-1");
 
-int main(int argc, char *argv[])
+   // if a version includes a dash, it should be the debrev dash - policy says so…
+   EXPECT_VERSION("0:0-0-0", GREATER, "0-0");
+
+   // do we like strange versions? Yes we like strange versions…
+   EXPECT_VERSION("0", EQUAL, "0");
+   EXPECT_VERSION("0", EQUAL, "00");
+}
+TEST(CompareVersionTest,DebianBug)
+{
+   // #205960
+   EXPECT_VERSION("3.0~rc1-1", LESS, "3.0-1");
+   // #573592 - debian policy 5.6.12
+   EXPECT_VERSION("1.0", EQUAL, "1.0-0");
+   EXPECT_VERSION("0.2", LESS, "1.0-0");
+   EXPECT_VERSION("1.0", LESS, "1.0-0+b1");
+   EXPECT_VERSION("1.0", GREATER, "1.0-0~");
+}
+TEST(CompareVersionTest,CuptTests)
 {
-   if (argc != 2)
-      return 1;
-   else
-      RunTest(argv[1]);
-
-   // Print any errors or warnings found
-   _error->DumpErrors();
-   return 0;
+   // "steal" the testcases from (old perl) cupt
+   EXPECT_VERSION("1.2.3", EQUAL, "1.2.3"); // identical
+   EXPECT_VERSION("4.4.3-2", EQUAL, "4.4.3-2"); // identical
+   EXPECT_VERSION("1:2ab:5", EQUAL, "1:2ab:5"); // this is correct...
+   EXPECT_VERSION("7:1-a:b-5", EQUAL, "7:1-a:b-5"); // and this
+   EXPECT_VERSION("57:1.2.3abYZ+~-4-5", EQUAL, "57:1.2.3abYZ+~-4-5"); // and those too
+   EXPECT_VERSION("1.2.3", EQUAL, "0:1.2.3"); // zero epoch
+   EXPECT_VERSION("1.2.3", EQUAL, "1.2.3-0"); // zero revision
+   EXPECT_VERSION("009", EQUAL, "9"); // zeroes…
+   EXPECT_VERSION("009ab5", EQUAL, "9ab5"); // there as well
+   EXPECT_VERSION("1.2.3", LESS, "1.2.3-1"); // added non-zero revision
+   EXPECT_VERSION("1.2.3", LESS, "1.2.4"); // just bigger
+   EXPECT_VERSION("1.2.4", GREATER, "1.2.3"); // order doesn't matter
+   EXPECT_VERSION("1.2.24", GREATER, "1.2.3"); // bigger, eh?
+   EXPECT_VERSION("0.10.0", GREATER, "0.8.7"); // bigger, eh?
+   EXPECT_VERSION("3.2", GREATER, "2.3"); // major number rocks
+   EXPECT_VERSION("1.3.2a", GREATER, "1.3.2"); // letters rock
+   EXPECT_VERSION("0.5.0~git", LESS, "0.5.0~git2"); // numbers rock
+   EXPECT_VERSION("2a", LESS, "21"); // but not in all places
+   EXPECT_VERSION("1.3.2a", LESS, "1.3.2b"); // but there is another letter
+   EXPECT_VERSION("1:1.2.3", GREATER, "1.2.4"); // epoch rocks
+   EXPECT_VERSION("1:1.2.3", LESS, "1:1.2.4"); // bigger anyway
+   EXPECT_VERSION("1.2a+~bCd3", LESS, "1.2a++"); // tilde doesn't rock
+   EXPECT_VERSION("1.2a+~bCd3", GREATER, "1.2a+~"); // but first is longer!
+   EXPECT_VERSION("5:2", GREATER, "304-2"); // epoch rocks
+   EXPECT_VERSION("5:2", LESS, "304:2"); // so big epoch?
+   EXPECT_VERSION("25:2", GREATER, "3:2"); // 25 > 3, obviously
+   EXPECT_VERSION("1:2:123", LESS, "1:12:3"); // 12 > 2
+   EXPECT_VERSION("1.2-5", LESS, "1.2-3-5"); // 1.2 < 1.2-3
+   EXPECT_VERSION("5.10.0", GREATER, "5.005"); // preceding zeroes don't matters
+   EXPECT_VERSION("3a9.8", LESS, "3.10.2"); // letters are before all letter symbols
+   EXPECT_VERSION("3a9.8", GREATER, "3~10"); // but after the tilde
+   EXPECT_VERSION("1.4+OOo3.0.0~", LESS, "1.4+OOo3.0.0-4"); // another tilde check
+   EXPECT_VERSION("2.4.7-1", LESS, "2.4.7-z"); // revision comparing
+   EXPECT_VERSION("1.002-1+b2", GREATER, "1.00"); // whatever...
+   /* disabled as dpkg doesn't like them… (versions with illegal char)
+   EXPECT_VERSION("2.2.4-47978_Debian_lenny", EQUAL, "2.2.4-47978_Debian_lenny"); // and underscore...
+   // */
 }

+ 87 - 80
test/libapt/configuration_test.cc

@@ -5,135 +5,142 @@
 #include <string>
 #include <vector>
 
-#include "assert.h"
+#include <gtest/gtest.h>
 
-int main() {
+//FIXME: Test for configuration file parsing;
+// currently only integration/ tests test them implicitly
+
+TEST(ConfigurationTest,Lists)
+{
 	Configuration Cnf;
-	std::vector<std::string> fds;
 
 	Cnf.Set("APT::Keep-Fds::",28);
 	Cnf.Set("APT::Keep-Fds::",17);
 	Cnf.Set("APT::Keep-Fds::2",47);
 	Cnf.Set("APT::Keep-Fds::","broken");
-	fds = Cnf.FindVector("APT::Keep-Fds");
-	equals(fds[0], "28");
-	equals(fds[1], "17");
-	equals(fds[2], "47");
-	equals(fds[3], "broken");
-	equals(fds.size(), 4);
-	equals(Cnf.Exists("APT::Keep-Fds::2"), true);
-	equals(Cnf.Find("APT::Keep-Fds::2"), "47");
-	equals(Cnf.FindI("APT::Keep-Fds::2"), 47);
-	equals(Cnf.Exists("APT::Keep-Fds::3"), false);
-	equals(Cnf.Find("APT::Keep-Fds::3"), "");
-	equals(Cnf.FindI("APT::Keep-Fds::3", 56), 56);
-	equals(Cnf.Find("APT::Keep-Fds::3", "not-set"), "not-set");
+	std::vector<std::string> fds = Cnf.FindVector("APT::Keep-Fds");
+	ASSERT_EQ(4, fds.size());
+	EXPECT_EQ("28", fds[0]);
+	EXPECT_EQ("17", fds[1]);
+	EXPECT_EQ("47", fds[2]);
+	EXPECT_EQ("broken", fds[3]);
+
+	EXPECT_TRUE(Cnf.Exists("APT::Keep-Fds::2"));
+	EXPECT_EQ("47", Cnf.Find("APT::Keep-Fds::2"));
+	EXPECT_EQ(47, Cnf.FindI("APT::Keep-Fds::2"));
+	EXPECT_FALSE(Cnf.Exists("APT::Keep-Fds::3"));
+	EXPECT_EQ("", Cnf.Find("APT::Keep-Fds::3"));
+	EXPECT_EQ(56, Cnf.FindI("APT::Keep-Fds::3", 56));
+	EXPECT_EQ("not-set", Cnf.Find("APT::Keep-Fds::3", "not-set"));
 
 	Cnf.Clear("APT::Keep-Fds::2");
+	EXPECT_TRUE(Cnf.Exists("APT::Keep-Fds::2"));
 	fds = Cnf.FindVector("APT::Keep-Fds");
-	equals(fds[0], "28");
-	equals(fds[1], "17");
-	equals(fds[2], "");
-	equals(fds[3], "broken");
-	equals(fds.size(), 4);
-	equals(Cnf.Exists("APT::Keep-Fds::2"), true);
+	ASSERT_EQ(4, fds.size());
+	EXPECT_EQ("28", fds[0]);
+	EXPECT_EQ("17", fds[1]);
+	EXPECT_EQ("", fds[2]);
+	EXPECT_EQ("broken", fds[3]);
 
 	Cnf.Clear("APT::Keep-Fds",28);
 	fds = Cnf.FindVector("APT::Keep-Fds");
-	equals(fds[0], "17");
-	equals(fds[1], "");
-	equals(fds[2], "broken");
-	equals(fds.size(), 3);
+	ASSERT_EQ(3, fds.size());
+	EXPECT_EQ("17", fds[0]);
+	EXPECT_EQ("", fds[1]);
+	EXPECT_EQ("broken", fds[2]);
 
 	Cnf.Clear("APT::Keep-Fds","");
-	equals(Cnf.Exists("APT::Keep-Fds::2"), false);
+	EXPECT_FALSE(Cnf.Exists("APT::Keep-Fds::2"));
 
 	Cnf.Clear("APT::Keep-Fds",17);
 	Cnf.Clear("APT::Keep-Fds","broken");
 	fds = Cnf.FindVector("APT::Keep-Fds");
-	equals(fds.empty(), true);
+	EXPECT_TRUE(fds.empty());
 
 	Cnf.Set("APT::Keep-Fds::",21);
 	Cnf.Set("APT::Keep-Fds::",42);
 	fds = Cnf.FindVector("APT::Keep-Fds");
-	equals(fds[0], "21");
-	equals(fds[1], "42");
-	equals(fds.size(), 2);
+	ASSERT_EQ(2, fds.size());
+	EXPECT_EQ("21", fds[0]);
+	EXPECT_EQ("42", fds[1]);
 
 	Cnf.Clear("APT::Keep-Fds");
 	fds = Cnf.FindVector("APT::Keep-Fds");
-	equals(fds.empty(), true);
+	EXPECT_TRUE(fds.empty());
+}
+TEST(ConfigurationTest,Integers)
+{
+	Configuration Cnf;
 
 	Cnf.CndSet("APT::Version", 42);
 	Cnf.CndSet("APT::Version", "66");
-	equals(Cnf.Find("APT::Version"), "42");
-	equals(Cnf.FindI("APT::Version"), 42);
-	equals(Cnf.Find("APT::Version", "33"), "42");
-	equals(Cnf.FindI("APT::Version", 33), 42);
-	equals(Cnf.Find("APT2::Version", "33"), "33");
-	equals(Cnf.FindI("APT2::Version", 33), 33);
-
-	equals(Cnf.FindFile("Dir::State"), "");
-	equals(Cnf.FindFile("Dir::Aptitude::State"), "");
+	EXPECT_EQ("42", Cnf.Find("APT::Version"));
+	EXPECT_EQ(42, Cnf.FindI("APT::Version"));
+	EXPECT_EQ("42", Cnf.Find("APT::Version", "33"));
+	EXPECT_EQ(42, Cnf.FindI("APT::Version", 33));
+	EXPECT_EQ("33", Cnf.Find("APT2::Version", "33"));
+	EXPECT_EQ(33, Cnf.FindI("APT2::Version", 33));
+}
+TEST(ConfigurationTest,DirsAndFiles)
+{
+	Configuration Cnf;
+
+	EXPECT_EQ("", Cnf.FindFile("Dir::State"));
+	EXPECT_EQ("", Cnf.FindFile("Dir::Aptitude::State"));
 	Cnf.Set("Dir", "/srv/sid");
-	equals(Cnf.FindFile("Dir::State"), "");
+	EXPECT_EQ("", Cnf.FindFile("Dir::State"));
 	Cnf.Set("Dir::State", "var/lib/apt");
 	Cnf.Set("Dir::Aptitude::State", "var/lib/aptitude");
-	equals(Cnf.FindFile("Dir::State"), "/srv/sid/var/lib/apt");
-	equals(Cnf.FindFile("Dir::Aptitude::State"), "/srv/sid/var/lib/aptitude");
+	EXPECT_EQ("/srv/sid/var/lib/apt", Cnf.FindFile("Dir::State"));
+	EXPECT_EQ("/srv/sid/var/lib/aptitude", Cnf.FindFile("Dir::Aptitude::State"));
 
 	Cnf.Set("RootDir", "/");
-	equals(Cnf.FindFile("Dir::State"), "/srv/sid/var/lib/apt");
-	equals(Cnf.FindFile("Dir::Aptitude::State"), "/srv/sid/var/lib/aptitude");
+	EXPECT_EQ("/srv/sid/var/lib/apt", Cnf.FindFile("Dir::State"));
+	EXPECT_EQ("/srv/sid/var/lib/aptitude", Cnf.FindFile("Dir::Aptitude::State"));
 	Cnf.Set("RootDir", "//./////.////");
-	equals(Cnf.FindFile("Dir::State"), "/srv/sid/var/lib/apt");
-	equals(Cnf.FindFile("Dir::Aptitude::State"), "/srv/sid/var/lib/aptitude");
+	EXPECT_EQ("/srv/sid/var/lib/apt", Cnf.FindFile("Dir::State"));
+	EXPECT_EQ("/srv/sid/var/lib/aptitude", Cnf.FindFile("Dir::Aptitude::State"));
 	Cnf.Set("RootDir", "/rootdir");
-	equals(Cnf.FindFile("Dir::State"), "/rootdir/srv/sid/var/lib/apt");
-	equals(Cnf.FindFile("Dir::Aptitude::State"), "/rootdir/srv/sid/var/lib/aptitude");
+	EXPECT_EQ("/rootdir/srv/sid/var/lib/apt", Cnf.FindFile("Dir::State"));
+	EXPECT_EQ("/rootdir/srv/sid/var/lib/aptitude", Cnf.FindFile("Dir::Aptitude::State"));
 	Cnf.Set("RootDir", "/rootdir/");
-	equals(Cnf.FindFile("Dir::State"), "/rootdir/srv/sid/var/lib/apt");
-	equals(Cnf.FindFile("Dir::Aptitude::State"), "/rootdir/srv/sid/var/lib/aptitude");
+	EXPECT_EQ("/rootdir/srv/sid/var/lib/apt", Cnf.FindFile("Dir::State"));
+	EXPECT_EQ("/rootdir/srv/sid/var/lib/aptitude", Cnf.FindFile("Dir::Aptitude::State"));
 
 	Cnf.Set("Dir::State", "/dev/null");
 	Cnf.Set("Dir::State::lists", "lists/");
-	equals(Cnf.FindDir("Dir::State"), "/rootdir/dev/null");
-	equals(Cnf.FindDir("Dir::State::lists"), "/rootdir/dev/null");
-
-	Cnf.Set("Moo::Bar", "1");
-	Cnf.Clear();
-	equals(Cnf.Find("Moo::Bar"), "");
+	EXPECT_EQ("/rootdir/dev/null", Cnf.FindDir("Dir::State"));
+	EXPECT_EQ("/rootdir/dev/null", Cnf.FindDir("Dir::State::lists"));
+}
+TEST(ConfigurationTest,Vector)
+{
+	Configuration Cnf;
 
 	std::vector<std::string> vec = Cnf.FindVector("Test::Vector", "");
-	equals(vec.size(), 0);
+	EXPECT_EQ(0, vec.size());
 	vec = Cnf.FindVector("Test::Vector", "foo");
-	equals(vec.size(), 1);
-	equals(vec[0], "foo");
+	ASSERT_EQ(1, vec.size());
+	EXPECT_EQ("foo", vec[0]);
 	vec = Cnf.FindVector("Test::Vector", "foo,bar");
-	equals(vec.size(), 2);
-	equals(vec[0], "foo");
-	equals(vec[1], "bar");
+	EXPECT_EQ(2, vec.size());
+	EXPECT_EQ("foo", vec[0]);
+	EXPECT_EQ("bar", vec[1]);
 	Cnf.Set("Test::Vector::", "baz");
 	Cnf.Set("Test::Vector::", "bob");
 	Cnf.Set("Test::Vector::", "dob");
 	vec = Cnf.FindVector("Test::Vector");
-	equals(vec.size(), 3);
-	equals(vec[0], "baz");
-	equals(vec[1], "bob");
-	equals(vec[2], "dob");
+	ASSERT_EQ(3, vec.size());
+	EXPECT_EQ("baz", vec[0]);
+	EXPECT_EQ("bob", vec[1]);
+	EXPECT_EQ("dob", vec[2]);
 	vec = Cnf.FindVector("Test::Vector", "foo,bar");
-	equals(vec.size(), 3);
-	equals(vec[0], "baz");
-	equals(vec[1], "bob");
-	equals(vec[2], "dob");
+	ASSERT_EQ(3, vec.size());
+	EXPECT_EQ("baz", vec[0]);
+	EXPECT_EQ("bob", vec[1]);
+	EXPECT_EQ("dob", vec[2]);
 	Cnf.Set("Test::Vector", "abel,bravo");
 	vec = Cnf.FindVector("Test::Vector", "foo,bar");
-	equals(vec.size(), 2);
-	equals(vec[0], "abel");
-	equals(vec[1], "bravo");
-
-	//FIXME: Test for configuration file parsing;
-	// currently only integration/ tests test them implicitly
-
-	return 0;
+	ASSERT_EQ(2, vec.size());
+	EXPECT_EQ("abel", vec[0]);
+	EXPECT_EQ("bravo", vec[1]);
 }

+ 77 - 0
test/libapt/file-helpers.cc

@@ -0,0 +1,77 @@
+#include <apt-pkg/fileutl.h>
+
+#include <string>
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#include <gtest/gtest.h>
+
+#include "file-helpers.h"
+
+void helperCreateTemporaryDirectory(std::string const &id, std::string &dir)
+{
+   std::string const strtempdir = GetTempDir().append("/apt-tests-").append(id).append(".XXXXXX");
+   char * tempdir = strdup(strtempdir.c_str());
+   ASSERT_STREQ(tempdir, mkdtemp(tempdir));
+   dir = tempdir;
+   free(tempdir);
+}
+void helperRemoveDirectory(std::string const &dir)
+{
+   // basic sanity check to avoid removing random directories based on earlier failures
+   if (dir.find("/apt-tests-") == std::string::npos || dir.find_first_of("*?") != std::string::npos)
+      FAIL() << "Directory '" << dir << "' seems invalid. It is therefore not removed!";
+   else
+      ASSERT_EQ(0, system(std::string("rm -rf ").append(dir).c_str()));
+}
+void helperCreateFile(std::string const &dir, std::string const &name)
+{
+   std::string file = dir;
+   file.append("/");
+   file.append(name);
+   int const fd = creat(file.c_str(), 0600);
+   ASSERT_NE(-1, fd);
+   close(fd);
+}
+void helperCreateDirectory(std::string const &dir, std::string const &name)
+{
+   std::string file = dir;
+   file.append("/");
+   file.append(name);
+   ASSERT_TRUE(CreateDirectory(dir, file));
+}
+void helperCreateLink(std::string const &dir, std::string const &targetname, std::string const &linkname)
+{
+   std::string target = dir;
+   target.append("/");
+   target.append(targetname);
+   std::string link = dir;
+   link.append("/");
+   link.append(linkname);
+   ASSERT_EQ(0, symlink(target.c_str(), link.c_str()));
+}
+void helperCreateTemporaryFile(std::string const &id, FileFd &fd, char * * const filename, char const * const content)
+{
+   std::string name("apt-test-");
+   name.append(id).append(".XXXXXXXX");
+   char * tempfile = strdup(name.c_str());
+   int tempfile_fd = mkstemp(tempfile);
+   ASSERT_NE(-1, tempfile_fd);
+   if (filename != NULL)
+      *filename = tempfile;
+   else
+   {
+      unlink(tempfile);
+      free(tempfile);
+   }
+
+   EXPECT_TRUE(fd.OpenDescriptor(tempfile_fd, FileFd::ReadWrite));
+   if (content != NULL)
+   {
+      ASSERT_TRUE(fd.Write(content, strlen(content)));
+      fd.Seek(0);
+   }
+}

+ 29 - 0
test/libapt/file-helpers.h

@@ -0,0 +1,29 @@
+#ifndef APT_TESTS_FILE_HELPERS
+#define APT_TESTS_FILE_HELPERS
+
+#include <string>
+
+#include <gtest/gtest.h>
+
+class FileFd;
+
+#define createTemporaryDirectory(id, dir) \
+   ASSERT_NO_FATAL_FAILURE(helperCreateTemporaryDirectory(id, dir))
+void helperCreateTemporaryDirectory(std::string const &id, std::string &dir);
+#define removeDirectory(dir) \
+   ASSERT_NO_FATAL_FAILURE(helperRemoveDirectory(dir))
+void helperRemoveDirectory(std::string const &dir);
+#define createFile(dir, name) \
+   ASSERT_NO_FATAL_FAILURE(helperCreateFile(dir, name))
+void helperCreateFile(std::string const &dir, std::string const &name);
+#define createDirectory(dir, name) \
+   ASSERT_NO_FATAL_FAILURE(helperCreateDirectory(dir, name))
+void helperCreateDirectory(std::string const &dir, std::string const &name);
+#define createLink(dir, targetname, linkname) \
+   ASSERT_NO_FATAL_FAILURE(helperCreateLink(dir, targetname, linkname))
+void helperCreateLink(std::string const &dir, std::string const &targetname, std::string const &linkname);
+#define createTemporaryFile(id, fd, filename, content) \
+   ASSERT_NO_FATAL_FAILURE(helperCreateTemporaryFile(id, fd, filename, content))
+void helperCreateTemporaryFile(std::string const &id, FileFd &fd, char * * const filename, char const * const content);
+
+#endif

+ 131 - 141
test/libapt/fileutl_test.cc

@@ -2,151 +2,148 @@
 
 #include <apt-pkg/error.h>
 #include <apt-pkg/fileutl.h>
+#include <apt-pkg/strutl.h>
 #include <apt-pkg/aptconfiguration.h>
 
 #include <string>
 #include <vector>
 #include <stdlib.h>
-#include <sys/stat.h>
 #include <string.h>
 
-#include "assert.h"
+#include <gtest/gtest.h>
 
-static void assertStringEquals(char const * const expect, char const * const got, unsigned long const line) {
-	if (strncmp(expect, got, strlen(expect)) == 0)
-		return;
-	OutputAssertEqual(expect, "==", got, line);
-}
-#define strequals(x,y) assertStringEquals(x, y, __LINE__)
+#include "file-helpers.h"
 
-static bool
-TestFileFd(mode_t const a_umask, mode_t const ExpectedFilePermission, unsigned int const filemode, APT::Configuration::Compressor const &compressor)
+static void TestFileFd(mode_t const a_umask, mode_t const ExpectedFilePermission,
+      unsigned int const filemode, APT::Configuration::Compressor const &compressor)
 {
-   FileFd f;
-   struct stat buf;
+   std::string trace;
+   strprintf(trace, "TestFileFd: Compressor: %s umask: %#o permission: %#o mode: %d", compressor.Name.c_str(), a_umask, ExpectedFilePermission, filemode);
+   SCOPED_TRACE(trace);
+
    static const char* fname = "apt-filefd-test.txt";
    if (FileExists(fname) == true)
-      equals(unlink(fname), 0);
+      EXPECT_EQ(0, unlink(fname));
 
+   FileFd f;
    umask(a_umask);
-   equals(f.Open(fname, filemode, compressor), true);
-   equals(f.IsOpen(), true);
-   equals(f.Failed(), false);
-   equals(umask(a_umask), a_umask);
+   EXPECT_TRUE(f.Open(fname, filemode, compressor));
+   EXPECT_TRUE(f.IsOpen());
+   EXPECT_FALSE(f.Failed());
+   EXPECT_EQ(umask(a_umask), a_umask);
 
    std::string test = "This is a test!\n";
-   equals(f.Write(test.c_str(), test.size()), true);
-   equals(f.IsOpen(), true);
-   equals(f.Failed(), false);
+   EXPECT_TRUE(f.Write(test.c_str(), test.size()));
+   EXPECT_TRUE(f.IsOpen());
+   EXPECT_FALSE(f.Failed());
 
    f.Close();
-   equals(f.IsOpen(), false);
-   equals(f.Failed(), false);
-
-   equals(f.Open(fname, FileFd::ReadOnly, compressor), true);
-   equals(f.IsOpen(), true);
-   equals(f.Failed(), false);
-   equals(f.Eof(), false);
-   equalsNot(f.FileSize(), 0);
-   equals(f.Failed(), false);
-   equalsNot(f.ModificationTime(), 0);
-   equals(f.Failed(), false);
+   EXPECT_FALSE(f.IsOpen());
+   EXPECT_FALSE(f.Failed());
+
+   EXPECT_TRUE(f.Open(fname, FileFd::ReadOnly, compressor));
+   EXPECT_TRUE(f.IsOpen());
+   EXPECT_FALSE(f.Failed());
+   EXPECT_FALSE(f.Eof());
+   EXPECT_NE(0, f.FileSize());
+   EXPECT_FALSE(f.Failed());
+   EXPECT_NE(0, f.ModificationTime());
+   EXPECT_FALSE(f.Failed());
 
    // ensure the memory is as predictably messed up
-# define APT_INIT_READBACK \
+#define APT_INIT_READBACK \
    char readback[20]; \
    memset(readback, 'D', sizeof(readback)/sizeof(readback[0])); \
    readback[19] = '\0';
+#define EXPECT_N_STR(expect, actual) \
+   EXPECT_EQ(0, strncmp(expect, actual, strlen(expect)));
+
    {
       APT_INIT_READBACK
       char const * const expect = "This";
-      equals(f.Read(readback, strlen(expect)), true);
-      equals(f.Failed(), false);
-      equals(f.Eof(), false);
-      strequals(expect, readback);
-      equals(strlen(expect), f.Tell());
+      EXPECT_TRUE(f.Read(readback, strlen(expect)));
+      EXPECT_FALSE(f.Failed());
+      EXPECT_FALSE(f.Eof());
+      EXPECT_N_STR(expect, readback);
+      EXPECT_EQ(strlen(expect), f.Tell());
    }
    {
       APT_INIT_READBACK
       char const * const expect = "test!\n";
-      equals(f.Skip((test.size() - f.Tell()) - strlen(expect)), true);
-      equals(f.Read(readback, strlen(expect)), true);
-      equals(f.Failed(), false);
-      equals(f.Eof(), false);
-      strequals(expect, readback);
-      equals(test.size(), f.Tell());
+      EXPECT_TRUE(f.Skip((test.size() - f.Tell()) - strlen(expect)));
+      EXPECT_TRUE(f.Read(readback, strlen(expect)));
+      EXPECT_FALSE(f.Failed());
+      EXPECT_FALSE(f.Eof());
+      EXPECT_N_STR(expect, readback);
+      EXPECT_EQ(test.size(), f.Tell());
    }
    {
       APT_INIT_READBACK
-      equals(f.Seek(0), true);
-      equals(f.Eof(), false);
-      equals(f.Read(readback, 20, true), true);
-      equals(f.Failed(), false);
-      equals(f.Eof(), true);
-      strequals(test.c_str(), readback);
-      equals(f.Size(), f.Tell());
+      EXPECT_TRUE(f.Seek(0));
+      EXPECT_FALSE(f.Eof());
+      EXPECT_TRUE(f.Read(readback, 20, true));
+      EXPECT_FALSE(f.Failed());
+      EXPECT_TRUE(f.Eof());
+      EXPECT_N_STR(test.c_str(), readback);
+      EXPECT_EQ(f.Size(), f.Tell());
    }
    {
       APT_INIT_READBACK
-      equals(f.Seek(0), true);
-      equals(f.Eof(), false);
-      equals(f.Read(readback, test.size(), true), true);
-      equals(f.Failed(), false);
-      equals(f.Eof(), false);
-      strequals(test.c_str(), readback);
-      equals(f.Size(), f.Tell());
+      EXPECT_TRUE(f.Seek(0));
+      EXPECT_FALSE(f.Eof());
+      EXPECT_TRUE(f.Read(readback, test.size(), true));
+      EXPECT_FALSE(f.Failed());
+      EXPECT_FALSE(f.Eof());
+      EXPECT_N_STR(test.c_str(), readback);
+      EXPECT_EQ(f.Size(), f.Tell());
    }
    {
       APT_INIT_READBACK
-      equals(f.Seek(0), true);
-      equals(f.Eof(), false);
+      EXPECT_TRUE(f.Seek(0));
+      EXPECT_FALSE(f.Eof());
       unsigned long long actual;
-      equals(f.Read(readback, 20, &actual), true);
-      equals(f.Failed(), false);
-      equals(f.Eof(), true);
-      equals(test.size(), actual);
-      strequals(test.c_str(), readback);
-      equals(f.Size(), f.Tell());
+      EXPECT_TRUE(f.Read(readback, 20, &actual));
+      EXPECT_FALSE(f.Failed());
+      EXPECT_TRUE(f.Eof());
+      EXPECT_EQ(test.size(), actual);
+      EXPECT_N_STR(test.c_str(), readback);
+      EXPECT_EQ(f.Size(), f.Tell());
    }
    {
       APT_INIT_READBACK
-      equals(f.Seek(0), true);
-      equals(f.Eof(), false);
+      EXPECT_TRUE(f.Seek(0));
+      EXPECT_FALSE(f.Eof());
       f.ReadLine(readback, 20);
-      equals(f.Failed(), false);
-      equals(f.Eof(), false);
-      equals(test, readback);
-      equals(f.Size(), f.Tell());
+      EXPECT_FALSE(f.Failed());
+      EXPECT_FALSE(f.Eof());
+      EXPECT_EQ(test, readback);
+      EXPECT_EQ(f.Size(), f.Tell());
    }
    {
       APT_INIT_READBACK
-      equals(f.Seek(0), true);
-      equals(f.Eof(), false);
+      EXPECT_TRUE(f.Seek(0));
+      EXPECT_FALSE(f.Eof());
       char const * const expect = "This";
       f.ReadLine(readback, strlen(expect) + 1);
-      equals(f.Failed(), false);
-      equals(f.Eof(), false);
-      strequals(expect, readback);
-      equals(strlen(expect), f.Tell());
+      EXPECT_FALSE(f.Failed());
+      EXPECT_FALSE(f.Eof());
+      EXPECT_N_STR(expect, readback);
+      EXPECT_EQ(strlen(expect), f.Tell());
    }
 #undef APT_INIT_READBACK
 
    f.Close();
-   equals(f.IsOpen(), false);
-   equals(f.Failed(), false);
+   EXPECT_FALSE(f.IsOpen());
+   EXPECT_FALSE(f.Failed());
 
    // regression test for permission bug LP: #1304657
-   if (stat(fname, &buf) < 0)
-   {
-      _error->Errno("stat", "failed to stat");
-      return false;
-   }
-   equals(unlink(fname), 0);
-   equals(buf.st_mode & 0777, ExpectedFilePermission);
-   return true;
+   struct stat buf;
+   EXPECT_EQ(0, stat(fname, &buf));
+   EXPECT_EQ(0, unlink(fname));
+   EXPECT_EQ(ExpectedFilePermission, buf.st_mode & 0777);
 }
 
-static bool TestFileFd(unsigned int const filemode)
+static void TestFileFd(unsigned int const filemode)
 {
    std::vector<APT::Configuration::Compressor> compressors = APT::Configuration::getCompressors();
 
@@ -159,78 +156,71 @@ static bool TestFileFd(unsigned int const filemode)
       if ((filemode & FileFd::ReadWrite) == FileFd::ReadWrite &&
 	    (c->Name.empty() != true && c->Binary.empty() != true))
 	 continue;
-      if (TestFileFd(0002, 0664, filemode, *c) == false ||
-	    TestFileFd(0022, 0644, filemode, *c) == false ||
-	    TestFileFd(0077, 0600, filemode, *c) == false ||
-	    TestFileFd(0026, 0640, filemode, *c) == false)
-      {
-	 _error->DumpErrors();
-	 return false;
-      }
+      TestFileFd(0002, 0664, filemode, *c);
+      TestFileFd(0022, 0644, filemode, *c);
+      TestFileFd(0077, 0600, filemode, *c);
+      TestFileFd(0026, 0640, filemode, *c);
    }
-   return true;
 }
 
-int main(int const argc, char const * const * const argv)
+TEST(FileUtlTest, FileFD)
+{
+   std::string const startdir = SafeGetCWD();
+   EXPECT_FALSE(startdir.empty());
+   std::string tempdir;
+   createTemporaryDirectory("filefd", tempdir);
+   EXPECT_EQ(0, chdir(tempdir.c_str()));
+
+   TestFileFd(FileFd::WriteOnly | FileFd::Create);
+   TestFileFd(FileFd::WriteOnly | FileFd::Create | FileFd::Empty);
+   TestFileFd(FileFd::WriteOnly | FileFd::Create | FileFd::Exclusive);
+   TestFileFd(FileFd::WriteOnly | FileFd::Atomic);
+   TestFileFd(FileFd::WriteOnly | FileFd::Create | FileFd::Atomic);
+   // short-hands for ReadWrite with these modes
+   TestFileFd(FileFd::WriteEmpty);
+   TestFileFd(FileFd::WriteAny);
+   TestFileFd(FileFd::WriteTemp);
+   TestFileFd(FileFd::WriteAtomic);
+
+   EXPECT_EQ(0, chdir(startdir.c_str()));
+   removeDirectory(tempdir);
+}
+TEST(FileUtlTest, Glob)
 {
-   std::string startdir;
-   if (argc > 1 && DirectoryExists(argv[1]) == true) {
-      startdir = SafeGetCWD();
-      equals(chdir(argv[1]), 0);
-   }
-   if (TestFileFd(FileFd::WriteOnly | FileFd::Create) == false ||
-	 TestFileFd(FileFd::WriteOnly | FileFd::Create | FileFd::Empty) == false ||
-	 TestFileFd(FileFd::WriteOnly | FileFd::Create | FileFd::Exclusive) == false ||
-	 TestFileFd(FileFd::WriteOnly | FileFd::Atomic) == false ||
-	 TestFileFd(FileFd::WriteOnly | FileFd::Create | FileFd::Atomic) == false ||
-	 // short-hands for ReadWrite with these modes
-	 TestFileFd(FileFd::WriteEmpty) == false ||
-	 TestFileFd(FileFd::WriteAny) == false ||
-	 TestFileFd(FileFd::WriteTemp) == false ||
-	 TestFileFd(FileFd::WriteAtomic) == false)
-   {
-      return 1;
-   }
-   if (startdir.empty() == false)
-      equals(chdir(startdir.c_str()), 0);
-
    std::vector<std::string> files;
    // normal match
-   files = Glob("*.lst");
-   if (files.size() != 1)
-   {
-      _error->DumpErrors();
-      return 1;
-   }
+   files = Glob("*akefile");
+   EXPECT_EQ(1, files.size());
 
    // not there
    files = Glob("xxxyyyzzz");
-   if (files.size() != 0 || _error->PendingError())
-   {
-      _error->DumpErrors();
-      return 1;
-   }
+   EXPECT_TRUE(files.empty());
+   EXPECT_FALSE(_error->PendingError());
 
    // many matches (number is a bit random)
    files = Glob("*.cc");
-   if (files.size() < 10)
-   {
-      _error->DumpErrors();
-      return 1;
-   }
+   EXPECT_LT(10, files.size());
+}
+TEST(FileUtlTest, GetTempDir)
+{
+   char const * const envtmp = getenv("TMPDIR");
+   std::string old_tmpdir;
+   if (envtmp != NULL)
+      old_tmpdir = envtmp;
 
-   // GetTempDir()
    unsetenv("TMPDIR");
-   equals(GetTempDir(), "/tmp");
+   EXPECT_EQ("/tmp", GetTempDir());
 
    setenv("TMPDIR", "", 1);
-   equals(GetTempDir(), "/tmp");
+   EXPECT_EQ("/tmp", GetTempDir());
 
    setenv("TMPDIR", "/not-there-no-really-not", 1);
-   equals(GetTempDir(), "/tmp");
+   EXPECT_EQ("/tmp", GetTempDir());
 
    setenv("TMPDIR", "/usr", 1);
-   equals(GetTempDir(), "/usr");
+   EXPECT_EQ("/usr", GetTempDir());
 
-   return 0;
+   unsetenv("TMPDIR");
+   if (old_tmpdir.empty() == false)
+      setenv("TMPDIR", old_tmpdir.c_str(), 1);
 }

+ 66 - 50
test/libapt/getarchitectures_test.cc

@@ -6,56 +6,72 @@
 #include <string>
 #include <vector>
 
-#include "assert.h"
+#include <gtest/gtest.h>
 
-int main()
+TEST(ArchitecturesTest,SimpleLists)
 {
-	std::vector<std::string> vec;
-
-	_config->Set("APT::Architectures::1", "i386");
-	_config->Set("APT::Architectures::2", "amd64");
-	vec = APT::Configuration::getArchitectures(false);
-	equals(vec.size(), 2);
-	equals(vec[0], "i386");
-	equals(vec[1], "amd64");
-
-	_config->Set("APT::Architecture", "i386");
-	vec = APT::Configuration::getArchitectures(false);
-	equals(vec.size(), 2);
-	equals(vec[0], "i386");
-	equals(vec[1], "amd64");
-
-	_config->Set("APT::Architectures::2", "");
-	vec = APT::Configuration::getArchitectures(false);
-	equals(vec.size(), 1);
-	equals(vec[0], "i386");
-
-	_config->Set("APT::Architecture", "armel");
-	vec = APT::Configuration::getArchitectures(false);
-	equals(vec.size(), 2);
-	equals(vec[0], "armel");
-	equals(vec[1], "i386");
-
-	_config->Set("APT::Architectures::2", "armel");
-	vec = APT::Configuration::getArchitectures(false);
-	equals(vec.size(), 2);
-	equals(vec[0], "i386");
-	equals(vec[1], "armel");
-
-	_config->Set("APT::Architectures::2", "amd64");
-	_config->Set("APT::Architectures::3", "i386");
-	_config->Set("APT::Architectures::4", "armel");
-	_config->Set("APT::Architectures::5", "i386");
-	_config->Set("APT::Architectures::6", "amd64");
-	_config->Set("APT::Architectures::7", "armel");
-	_config->Set("APT::Architectures::8", "armel");
-	_config->Set("APT::Architectures::9", "amd64");
-	_config->Set("APT::Architectures::10", "amd64");
-	vec = APT::Configuration::getArchitectures(false);
-	equals(vec.size(), 3);
-	equals(vec[0], "i386");
-	equals(vec[1], "amd64");
-	equals(vec[2], "armel");
-
-	return 0;
+   _config->Clear();
+   std::vector<std::string> vec;
+
+   _config->Set("APT::Architectures::1", "i386");
+   _config->Set("APT::Architectures::2", "amd64");
+   vec = APT::Configuration::getArchitectures(false);
+   ASSERT_EQ(2, vec.size());
+   EXPECT_EQ("i386", vec[0]);
+   EXPECT_EQ("amd64", vec[1]);
+
+   _config->Set("APT::Architecture", "i386");
+   vec = APT::Configuration::getArchitectures(false);
+   ASSERT_EQ(2, vec.size());
+   EXPECT_EQ("i386", vec[0]);
+   EXPECT_EQ("amd64", vec[1]);
+
+   _config->Set("APT::Architectures::2", "");
+   vec = APT::Configuration::getArchitectures(false);
+   ASSERT_EQ(1, vec.size());
+   EXPECT_EQ("i386", vec[0]);
+
+   _config->Set("APT::Architecture", "armel");
+   vec = APT::Configuration::getArchitectures(false);
+   ASSERT_EQ(2, vec.size());
+   EXPECT_EQ("armel", vec[0]);
+   EXPECT_EQ("i386", vec[1]);
+
+   _config->Set("APT::Architectures::2", "armel");
+   vec = APT::Configuration::getArchitectures(false);
+   ASSERT_EQ(2, vec.size());
+   EXPECT_EQ("i386", vec[0]);
+   EXPECT_EQ("armel", vec[1]);
+
+   _config->Set("APT::Architectures", "armel,armhf");
+   vec = APT::Configuration::getArchitectures(false);
+   ASSERT_EQ(2, vec.size());
+   EXPECT_EQ("armel", vec[0]);
+   EXPECT_EQ("armhf", vec[1]);
+   _config->Clear();
+}
+TEST(ArchitecturesTest,Duplicates)
+{
+   _config->Clear();
+
+   _config->Set("APT::Architecture", "armel");
+   _config->Set("APT::Architectures::", "i386");
+   _config->Set("APT::Architectures::", "amd64");
+   _config->Set("APT::Architectures::", "i386");
+   _config->Set("APT::Architectures::", "armel");
+   _config->Set("APT::Architectures::", "i386");
+   _config->Set("APT::Architectures::", "amd64");
+   _config->Set("APT::Architectures::", "armel");
+   _config->Set("APT::Architectures::", "armel");
+   _config->Set("APT::Architectures::", "amd64");
+   _config->Set("APT::Architectures::", "amd64");
+   std::vector<std::string> vec = _config->FindVector("APT::Architectures");
+   ASSERT_EQ(10, vec.size());
+   vec = APT::Configuration::getArchitectures(false);
+   ASSERT_EQ(3, vec.size());
+   EXPECT_EQ("i386", vec[0]);
+   EXPECT_EQ("amd64", vec[1]);
+   EXPECT_EQ("armel", vec[2]);
+
+   _config->Clear();
 }

+ 223 - 189
test/libapt/getlanguages_test.cc

@@ -2,199 +2,233 @@
 
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/configuration.h>
+#include <apt-pkg/fileutl.h>
 
-#include "assert.h"
+#include <algorithm>
+#include <iostream>
 #include <string>
 #include <vector>
 
-#include <iostream>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <gtest/gtest.h>
+
+#include "file-helpers.h"
+
+TEST(LanguagesTest,Environment)
+{
+   _config->Clear();
+
+   char const* env[2];
+   env[0] = "de_DE.UTF-8";
+   env[1] = "";
+
+   std::vector<std::string> vec = APT::Configuration::getLanguages(false, false, env);
+   ASSERT_EQ(3 ,vec.size());
+   EXPECT_EQ("de_DE", vec[0]);
+   EXPECT_EQ("de", vec[1]);
+   EXPECT_EQ("en", vec[2]);
+
+   // Special: Check if the cache is actually in use
+   env[0] = "en_GB.UTF-8";
+   vec = APT::Configuration::getLanguages(false, true, env);
+   ASSERT_EQ(3, vec.size());
+   EXPECT_EQ("de_DE", vec[0]);
+   EXPECT_EQ("de", vec[1]);
+   EXPECT_EQ("en", vec[2]);
+
+   env[0] = "en_GB.UTF-8";
+   vec = APT::Configuration::getLanguages(false, false, env);
+   ASSERT_EQ(2, vec.size());
+   EXPECT_EQ("en_GB", vec[0]);
+   EXPECT_EQ("en", vec[1]);
+
+   // esperanto
+   env[0] = "eo.UTF-8";
+   vec = APT::Configuration::getLanguages(false, false, env);
+   ASSERT_EQ(2, vec.size());
+   EXPECT_EQ("eo", vec[0]);
+   EXPECT_EQ("en", vec[1]);
+
+   env[0] = "tr_DE@euro";
+   vec = APT::Configuration::getLanguages(false, false, env);
+   EXPECT_EQ(3, vec.size());
+   EXPECT_EQ("tr_DE", vec[0]);
+   EXPECT_EQ("tr", vec[1]);
+   EXPECT_EQ("en", vec[2]);
+
+   env[0] = "de_NO";
+   env[1] = "de_NO:en_GB:nb_NO:nb:no_NO:no:nn_NO:nn:da:sv:en";
+   vec = APT::Configuration::getLanguages(false, false, env);
+   EXPECT_EQ(6, vec.size());
+   EXPECT_EQ("de_NO", vec[0]);
+   EXPECT_EQ("de", vec[1]);
+   EXPECT_EQ("en_GB", vec[2]);
+   EXPECT_EQ("nb_NO", vec[3]);
+   EXPECT_EQ("nb", vec[4]);
+   EXPECT_EQ("en", vec[5]);
+
+   env[0] = "pt_PR.UTF-8";
+   env[1] = "";
+   vec = APT::Configuration::getLanguages(false, false, env);
+   EXPECT_EQ(3, vec.size());
+   EXPECT_EQ("pt_PR", vec[0]);
+   EXPECT_EQ("pt", vec[1]);
+   EXPECT_EQ("en", vec[2]);
+
+   env[0] = "ast_DE.UTF-8";
+   vec = APT::Configuration::getLanguages(false, false, env); // bogus, but syntactical correct
+   EXPECT_EQ(3, vec.size());
+   EXPECT_EQ("ast_DE", vec[0]);
+   EXPECT_EQ("ast", vec[1]);
+   EXPECT_EQ("en", vec[2]);
+
+   env[0] = "C";
+   vec = APT::Configuration::getLanguages(false, false, env);
+   EXPECT_EQ(1, vec.size());
+   EXPECT_EQ("en", vec[0]);
+
+   _config->Set("Acquire::Languages", "none");
+   env[0] = "C";
+   vec = APT::Configuration::getLanguages(false, false, env);
+   EXPECT_TRUE(vec.empty());
+
+   _config->Set("Acquire::Languages", "environment");
+   env[0] = "C";
+   vec = APT::Configuration::getLanguages(false, false, env);
+   EXPECT_EQ(1, vec.size());
+   EXPECT_EQ("en", vec[0]);
+
+   _config->Set("Acquire::Languages", "de");
+   env[0] = "C";
+   vec = APT::Configuration::getLanguages(false, false, env);
+   EXPECT_EQ(1, vec.size());
+   EXPECT_EQ("de", vec[0]);
+
+   _config->Set("Acquire::Languages", "fr");
+   env[0] = "ast_DE.UTF-8";
+   vec = APT::Configuration::getLanguages(false, false, env);
+   EXPECT_EQ(1, vec.size());
+   EXPECT_EQ("fr", vec[0]);
+
+   _config->Set("Acquire::Languages", "environment,en");
+   env[0] = "de_DE.UTF-8";
+   vec = APT::Configuration::getLanguages(false, false, env);
+   EXPECT_EQ(3, vec.size());
+   EXPECT_EQ("de_DE", vec[0]);
+   EXPECT_EQ("de", vec[1]);
+   EXPECT_EQ("en", vec[2]);
+   _config->Set("Acquire::Languages", "");
+
+   _config->Set("Acquire::Languages::1", "environment");
+   _config->Set("Acquire::Languages::2", "en");
+   env[0] = "de_DE.UTF-8";
+   vec = APT::Configuration::getLanguages(false, false, env);
+   EXPECT_EQ(3, vec.size());
+   EXPECT_EQ("de_DE", vec[0]);
+   EXPECT_EQ("de", vec[1]);
+   EXPECT_EQ("en", vec[2]);
+
+   _config->Set("Acquire::Languages::3", "de");
+   env[0] = "de_DE.UTF-8";
+   vec = APT::Configuration::getLanguages(false, false, env);
+   EXPECT_EQ(3, vec.size());
+   EXPECT_EQ("de_DE", vec[0]);
+   EXPECT_EQ("de", vec[1]);
+   EXPECT_EQ("en", vec[2]);
+
+   _config->Clear();
+}
 
-int main(int argc,char *argv[])
+TEST(LanguagesTest,TranslationFiles)
 {
-	if (argc != 2) {
-		std::cout << "One parameter expected - given " << argc << std::endl;
-		return 100;
-	}
-
-	char const* env[2];
-	env[0] = "de_DE.UTF-8";
-	env[1] = "";
-
-	std::vector<std::string> vec = APT::Configuration::getLanguages(false, false, env);
-	equals(vec.size(), 3);
-	equals(vec[0], "de_DE");
-	equals(vec[1], "de");
-	equals(vec[2], "en");
-
-	// Special: Check if the cache is actually in use
-		env[0] = "en_GB.UTF-8";
-		vec = APT::Configuration::getLanguages(false, true, env);
-		equals(vec.size(), 3);
-		equals(vec[0], "de_DE");
-		equals(vec[1], "de");
-		equals(vec[2], "en");
-
-	env[0] = "en_GB.UTF-8";
-	vec = APT::Configuration::getLanguages(false, false, env);
-	equals(vec.size(), 2);
-	equals(vec[0], "en_GB");
-	equals(vec[1], "en");
-
-	// esperanto
-	env[0] = "eo.UTF-8";
-	vec = APT::Configuration::getLanguages(false, false, env);
-	equals(vec.size(), 2);
-	equals(vec[0], "eo");
-	equals(vec[1], "en");
-
-	env[0] = "tr_DE@euro";
-	vec = APT::Configuration::getLanguages(false, false, env);
-	equals(vec.size(), 3);
-	equals(vec[0], "tr_DE");
-	equals(vec[1], "tr");
-	equals(vec[2], "en");
-
-	env[0] = "de_NO";
-	env[1] = "de_NO:en_GB:nb_NO:nb:no_NO:no:nn_NO:nn:da:sv:en";
-	vec = APT::Configuration::getLanguages(false, false, env);
-	equals(vec.size(), 6);
-	equals(vec[0], "de_NO");
-	equals(vec[1], "de");
-	equals(vec[2], "en_GB");
-	equals(vec[3], "nb_NO");
-	equals(vec[4], "nb");
-	equals(vec[5], "en");
-
-	env[0] = "pt_PR.UTF-8";
-	env[1] = "";
-	vec = APT::Configuration::getLanguages(false, false, env);
-	equals(vec.size(), 3);
-	equals(vec[0], "pt_PR");
-	equals(vec[1], "pt");
-	equals(vec[2], "en");
-
-	env[0] = "ast_DE.UTF-8";
-	vec = APT::Configuration::getLanguages(false, false, env); // bogus, but syntactical correct
-	equals(vec.size(), 3);
-	equals(vec[0], "ast_DE");
-	equals(vec[1], "ast");
-	equals(vec[2], "en");
-
-	env[0] = "C";
-	vec = APT::Configuration::getLanguages(false, false, env);
-	equals(vec.size(), 1);
-	equals(vec[0], "en");
-
-	_config->Set("Acquire::Languages", "none");
-	env[0] = "C";
-	vec = APT::Configuration::getLanguages(false, false, env);
-	equals(vec.size(), 0);
-
-	_config->Set("Acquire::Languages", "environment");
-	env[0] = "C";
-	vec = APT::Configuration::getLanguages(false, false, env);
-	equals(vec.size(), 1);
-	equals(vec[0], "en");
-
-	_config->Set("Acquire::Languages", "de");
-	env[0] = "C";
-	vec = APT::Configuration::getLanguages(false, false, env);
-	equals(vec.size(), 1);
-	equals(vec[0], "de");
-
-	_config->Set("Acquire::Languages", "fr");
-	env[0] = "ast_DE.UTF-8";
-	vec = APT::Configuration::getLanguages(false, false, env);
-	equals(vec.size(), 1);
-	equals(vec[0], "fr");
-
-	_config->Set("Acquire::Languages", "environment,en");
-	env[0] = "de_DE.UTF-8";
-	vec = APT::Configuration::getLanguages(false, false, env);
-	equals(vec.size(), 3);
-	equals(vec[0], "de_DE");
-	equals(vec[1], "de");
-	equals(vec[2], "en");
-	_config->Set("Acquire::Languages", "");
-
-	_config->Set("Acquire::Languages::1", "environment");
-	_config->Set("Acquire::Languages::2", "en");
-	env[0] = "de_DE.UTF-8";
-	vec = APT::Configuration::getLanguages(false, false, env);
-	equals(vec.size(), 3);
-	equals(vec[0], "de_DE");
-	equals(vec[1], "de");
-	equals(vec[2], "en");
-
-	_config->Set("Acquire::Languages::3", "de");
-	env[0] = "de_DE.UTF-8";
-	vec = APT::Configuration::getLanguages(false, false, env);
-	equals(vec.size(), 3);
-	equals(vec[0], "de_DE");
-	equals(vec[1], "de");
-	equals(vec[2], "en");
-
-	_config->Set("Dir::State::lists", argv[1]);
-	vec = APT::Configuration::getLanguages(true, false, env);
-	equals(vec.size(), 8);
-	equals(vec[0], "de_DE");
-	equals(vec[1], "de");
-	equals(vec[2], "en");
-	equals(vec[3], "none");
-	equalsOr4(vec[4], "pt", "tr", "ast_DE", "tlh_DE");
-	equalsOr4(vec[5], "tr", "pt", "ast_DE", "tlh_DE");
-	equalsOr4(vec[6], "tr", "pt", "ast_DE", "tlh_DE");
-	equalsOr4(vec[7], "tr", "pt", "ast_DE", "tlh_DE");
-	equalsNot(vec[4], vec[5]);
-	equalsNot(vec[4], vec[6]);
-	equalsNot(vec[4], vec[7]);
-	equalsNot(vec[5], vec[6]);
-	equalsNot(vec[5], vec[7]);
-	equalsNot(vec[6], vec[7]);
-
-	_config->Set("Acquire::Languages", "none");
-	vec = APT::Configuration::getLanguages(true, false, env);
-	equals(vec.size(), 1);
-	equals(vec[0], "none");
-	_config->Set("Acquire::Languages", "");
-
-	_config->Set("Dir::State::lists", "/non-existing-dir");
-	_config->Set("Acquire::Languages::1", "none");
-	env[0] = "de_DE.UTF-8";
-	vec = APT::Configuration::getLanguages(false, false, env);
-	equals(vec.size(), 0);
-	env[0] = "de_DE.UTF-8";
-	vec = APT::Configuration::getLanguages(true, false, env);
-	equals(vec.size(), 2);
-	equals(vec[0], "en");
-	equals(vec[1], "de");
-
-	_config->Set("Acquire::Languages::1", "fr");
-	_config->Set("Acquire::Languages", "de_DE");
-	env[0] = "de_DE.UTF-8";
-	vec = APT::Configuration::getLanguages(false, false, env);
-	equals(vec.size(), 1);
-	equals(vec[0], "de_DE");
-
-	_config->Set("Acquire::Languages", "none");
-	env[0] = "de_DE.UTF-8";
-	vec = APT::Configuration::getLanguages(true, false, env);
-	equals(vec.size(), 1);
-	equals(vec[0], "none");
-
-	_config->Set("Acquire::Languages", "");
-	//FIXME: Remove support for this deprecated setting
-		_config->Set("APT::Acquire::Translation", "ast_DE");
-		env[0] = "de_DE.UTF-8";
-		vec = APT::Configuration::getLanguages(true, false, env);
-		equals(vec.size(), 2);
-		equals(vec[0], "ast_DE");
-		equals(vec[1], "en");
-		_config->Set("APT::Acquire::Translation", "none");
-		env[0] = "de_DE.UTF-8";
-		vec = APT::Configuration::getLanguages(true, false, env);
-		equals(vec.size(), 1);
-		equals(vec[0], "en");
-
-	return 0;
+   _config->Clear();
+   _config->Set("Acquire::Languages::1", "environment");
+   _config->Set("Acquire::Languages::2", "en");
+   _config->Set("Acquire::Languages::3", "de");
+
+   char const* env[2];
+   env[0] = "de_DE.UTF-8";
+   env[1] = "";
+
+   std::string tempdir;
+   createTemporaryDirectory("languages", tempdir);
+
+#define createTranslation(lang) \
+   createFile(tempdir, std::string("/ftp.de.debian.org_debian_dists_sid_main_i18n_Translation-").append(lang));
+
+   createTranslation("tr");
+   createTranslation("pt");
+   createTranslation("se~");
+   createTranslation("st.bak");
+   createTranslation("ast_DE");
+   createTranslation("tlh%5fDE");
+
+   _config->Set("Dir::State::lists", tempdir);
+   std::vector<std::string> vec = APT::Configuration::getLanguages(true, false, env);
+   EXPECT_EQ(8, vec.size());
+   EXPECT_EQ("de_DE", vec[0]);
+   EXPECT_EQ("de", vec[1]);
+   EXPECT_EQ("en", vec[2]);
+   EXPECT_EQ("none", vec[3]);
+   EXPECT_NE(vec.end(), std::find(vec.begin(), vec.end(), "pt"));
+   EXPECT_NE(vec.end(), std::find(vec.begin(), vec.end(), "tr"));
+   EXPECT_NE(vec.end(), std::find(vec.begin(), vec.end(), "ast_DE"));
+   EXPECT_NE(vec.end(), std::find(vec.begin(), vec.end(), "tlh_DE"));
+   EXPECT_NE(vec[4], vec[5]);
+   EXPECT_NE(vec[4], vec[6]);
+   EXPECT_NE(vec[4], vec[7]);
+   EXPECT_NE(vec[5], vec[6]);
+   EXPECT_NE(vec[5], vec[7]);
+   EXPECT_NE(vec[6], vec[7]);
+
+   _config->Set("Acquire::Languages", "none");
+   vec = APT::Configuration::getLanguages(true, false, env);
+   EXPECT_EQ(1, vec.size());
+   EXPECT_EQ("none", vec[0]);
+   _config->Set("Acquire::Languages", "");
+
+   _config->Set("Dir::State::lists", "/non-existing-dir");
+   _config->Set("Acquire::Languages::1", "none");
+   env[0] = "de_DE.UTF-8";
+   vec = APT::Configuration::getLanguages(false, false, env);
+   EXPECT_TRUE(vec.empty());
+   env[0] = "de_DE.UTF-8";
+   vec = APT::Configuration::getLanguages(true, false, env);
+   EXPECT_EQ(2, vec.size());
+   EXPECT_EQ("en", vec[0]);
+   EXPECT_EQ("de", vec[1]);
+
+   _config->Set("Acquire::Languages::1", "fr");
+   _config->Set("Acquire::Languages", "de_DE");
+   env[0] = "de_DE.UTF-8";
+   vec = APT::Configuration::getLanguages(false, false, env);
+   EXPECT_EQ(1, vec.size());
+   EXPECT_EQ("de_DE", vec[0]);
+
+   _config->Set("Acquire::Languages", "none");
+   env[0] = "de_DE.UTF-8";
+   vec = APT::Configuration::getLanguages(true, false, env);
+   EXPECT_EQ(1, vec.size());
+   EXPECT_EQ("none", vec[0]);
+
+   _config->Set("Acquire::Languages", "");
+   //FIXME: Remove support for this deprecated setting
+   _config->Set("APT::Acquire::Translation", "ast_DE");
+   env[0] = "de_DE.UTF-8";
+   vec = APT::Configuration::getLanguages(true, false, env);
+   EXPECT_EQ(2, vec.size());
+   EXPECT_EQ("ast_DE", vec[0]);
+   EXPECT_EQ("en", vec[1]);
+   _config->Set("APT::Acquire::Translation", "none");
+   env[0] = "de_DE.UTF-8";
+   vec = APT::Configuration::getLanguages(true, false, env);
+   EXPECT_EQ(1, vec.size());
+   EXPECT_EQ("en", vec[0]);
+
+
+   EXPECT_EQ(0, system(std::string("rm -rf ").append(tempdir).c_str()));
+   _config->Clear();
 }

+ 95 - 64
test/libapt/getlistoffilesindir_test.cc

@@ -6,71 +6,102 @@
 #include <vector>
 #include <iostream>
 
-#include "assert.h"
+#include <gtest/gtest.h>
 
-#define P(x)	std::string(argv[1]).append("/").append(x)
+#include "file-helpers.h"
 
-int main(int argc,char *argv[])
+#define P(x)	std::string(tempdir).append("/").append(x)
+
+TEST(FileUtlTest,GetListOfFilesInDir)
 {
-	if (argc != 2) {
-		std::cout << "One parameter expected - given " << argc << std::endl;
-		return 100;
-	}
-
-	// Files with no extension
-	std::vector<std::string> files = GetListOfFilesInDir(argv[1], "", true);
-	equals(files.size(), 2);
-	equals(files[0], P("01yet-anothernormalfile"));
-	equals(files[1], P("anormalfile"));
-
-	// Files with no extension - should be the same as above
-	files = GetListOfFilesInDir(argv[1], "", true, true);
-	equals(files.size(), 2);
-	equals(files[0], P("01yet-anothernormalfile"));
-	equals(files[1], P("anormalfile"));
-
-	// Files with impossible extension
-	files = GetListOfFilesInDir(argv[1], "impossible", true);
-	equals(files.size(), 0);
-
-	// Files with impossible or no extension
-	files = GetListOfFilesInDir(argv[1], "impossible", true, true);
-	equals(files.size(), 2);
-	equals(files[0], P("01yet-anothernormalfile"));
-	equals(files[1], P("anormalfile"));
-
-	// Files with list extension - nothing more
-	files = GetListOfFilesInDir(argv[1], "list", true);
-	equals(files.size(), 4);
-	equals(files[0], P("01yet-anotherapt.list"));
-	equals(files[1], P("anormalapt.list"));
-	equals(files[2], P("linkedfile.list"));
-	equals(files[3], P("multi.dot.list"));
-
-	// Files with conf or no extension
-	files = GetListOfFilesInDir(argv[1], "conf", true, true);
-	equals(files.size(), 5);
-	equals(files[0], P("01yet-anotherapt.conf"));
-	equals(files[1], P("01yet-anothernormalfile"));
-	equals(files[2], P("anormalapt.conf"));
-	equals(files[3], P("anormalfile"));
-	equals(files[4], P("multi.dot.conf"));
-
-	// Files with disabled extension - nothing more
-	files = GetListOfFilesInDir(argv[1], "disabled", true);
-	equals(files.size(), 3);
-	equals(files[0], P("disabledfile.conf.disabled"));
-	equals(files[1], P("disabledfile.disabled"));
-	equals(files[2], P("disabledfile.list.disabled"));
-
-	// Files with disabled or no extension
-	files = GetListOfFilesInDir(argv[1], "disabled", true, true);
-	equals(files.size(), 5);
-	equals(files[0], P("01yet-anothernormalfile"));
-	equals(files[1], P("anormalfile"));
-	equals(files[2], P("disabledfile.conf.disabled"));
-	equals(files[3], P("disabledfile.disabled"));
-	equals(files[4], P("disabledfile.list.disabled"));
-
-	return 0;
+   std::string tempdir;
+   createTemporaryDirectory("getlistoffiles", tempdir);
+
+   createFile(tempdir, "anormalfile");
+   createFile(tempdir, "01yet-anothernormalfile");
+   createFile(tempdir, "anormalapt.conf");
+   createFile(tempdir, "01yet-anotherapt.conf");
+   createFile(tempdir, "anormalapt.list");
+   createFile(tempdir, "01yet-anotherapt.list");
+   createFile(tempdir, "wrongextension.wron");
+   createFile(tempdir, "wrong-extension.wron");
+   createFile(tempdir, "strangefile.");
+   createFile(tempdir, "s.t.r.a.n.g.e.f.i.l.e");
+   createFile(tempdir, ".hiddenfile");
+   createFile(tempdir, ".hiddenfile.conf");
+   createFile(tempdir, ".hiddenfile.list");
+   createFile(tempdir, "multi..dot");
+   createFile(tempdir, "multi.dot.conf");
+   createFile(tempdir, "multi.dot.list");
+   createFile(tempdir, "disabledfile.disabled");
+   createFile(tempdir, "disabledfile.conf.disabled");
+   createFile(tempdir, "disabledfile.list.disabled");
+   createFile(tempdir, "invälid.conf");
+   createFile(tempdir, "invalíd");
+   createFile(tempdir, "01invalíd");
+   createDirectory(tempdir, "invaliddir");
+   createDirectory(tempdir, "directory.conf");
+   createDirectory(tempdir, "directory.list");
+   createDirectory(tempdir, "directory.wron");
+   createDirectory(tempdir, "directory.list.disabled");
+   createLink(tempdir, "anormalfile", "linkedfile.list");
+   createLink(tempdir, "invaliddir", "linkeddir.list");
+   createLink(tempdir, "non-existing-file", "brokenlink.list");
+
+   // Files with no extension
+   std::vector<std::string> files = GetListOfFilesInDir(tempdir, "", true);
+   ASSERT_EQ(2, files.size());
+   EXPECT_EQ(P("01yet-anothernormalfile"), files[0]);
+   EXPECT_EQ(P("anormalfile"), files[1]);
+
+   // Files with no extension - should be the same as above
+   files = GetListOfFilesInDir(tempdir, "", true, true);
+   ASSERT_EQ(2, files.size());
+   EXPECT_EQ(P("01yet-anothernormalfile"), files[0]);
+   EXPECT_EQ(P("anormalfile"), files[1]);
+
+   // Files with impossible extension
+   files = GetListOfFilesInDir(tempdir, "impossible", true);
+   EXPECT_TRUE(files.empty());
+
+   // Files with impossible or no extension
+   files = GetListOfFilesInDir(tempdir, "impossible", true, true);
+   ASSERT_EQ(2, files.size());
+   EXPECT_EQ(P("01yet-anothernormalfile"), files[0]);
+   EXPECT_EQ(P("anormalfile"), files[1]);
+
+   // Files with list extension - nothing more
+   files = GetListOfFilesInDir(tempdir, "list", true);
+   ASSERT_EQ(4, files.size());
+   EXPECT_EQ(P("01yet-anotherapt.list"), files[0]);
+   EXPECT_EQ(P("anormalapt.list"), files[1]);
+   EXPECT_EQ(P("linkedfile.list"), files[2]);
+   EXPECT_EQ(P("multi.dot.list"), files[3]);
+
+   // Files with conf or no extension
+   files = GetListOfFilesInDir(tempdir, "conf", true, true);
+   ASSERT_EQ(5, files.size());
+   EXPECT_EQ(P("01yet-anotherapt.conf"), files[0]);
+   EXPECT_EQ(P("01yet-anothernormalfile"), files[1]);
+   EXPECT_EQ(P("anormalapt.conf"), files[2]);
+   EXPECT_EQ(P("anormalfile"), files[3]);
+   EXPECT_EQ(P("multi.dot.conf"), files[4]);
+
+   // Files with disabled extension - nothing more
+   files = GetListOfFilesInDir(tempdir, "disabled", true);
+   ASSERT_EQ(3, files.size());
+   EXPECT_EQ(P("disabledfile.conf.disabled"), files[0]);
+   EXPECT_EQ(P("disabledfile.disabled"), files[1]);
+   EXPECT_EQ(P("disabledfile.list.disabled"), files[2]);
+
+   // Files with disabled or no extension
+   files = GetListOfFilesInDir(tempdir, "disabled", true, true);
+   ASSERT_EQ(5, files.size());
+   EXPECT_EQ(P("01yet-anothernormalfile"), files[0]);
+   EXPECT_EQ(P("anormalfile"), files[1]);
+   EXPECT_EQ(P("disabledfile.conf.disabled"), files[2]);
+   EXPECT_EQ(P("disabledfile.disabled"), files[3]);
+   EXPECT_EQ(P("disabledfile.list.disabled"), files[4]);
+
+   removeDirectory(tempdir);
 }

+ 116 - 97
test/libapt/globalerror_test.cc

@@ -7,110 +7,129 @@
 #include <errno.h>
 #include <string.h>
 
-#include "assert.h"
+#include <gtest/gtest.h>
 
-int main()
+TEST(GlobalErrorTest,BasicDiscard)
 {
-	std::string const textOfErrnoZero(strerror(0));
+   GlobalError e;
+   EXPECT_TRUE(e.empty());
+   EXPECT_FALSE(e.PendingError());
+   EXPECT_FALSE(e.Notice("%s Notice", "A"));
+   EXPECT_TRUE(e.empty());
+   EXPECT_FALSE(e.empty(GlobalError::DEBUG));
+   EXPECT_FALSE(e.PendingError());
+   EXPECT_FALSE(e.Error("%s horrible %s %d times", "Something", "happened", 2));
+   EXPECT_TRUE(e.PendingError());
 
-	equals(_error->empty(), true);
-	equals(_error->PendingError(), false);
-	equals(_error->Notice("%s Notice", "A"), false);
-	equals(_error->empty(), true);
-	equals(_error->empty(GlobalError::DEBUG), false);
-	equals(_error->PendingError(), false);
-	equals(_error->Error("%s horrible %s %d times", "Something", "happened", 2), false);
-	equals(_error->PendingError(), true);
-	std::string text;
-	equals(_error->PopMessage(text), false);
-	equals(_error->PendingError(), true);
-	equals(text, "A Notice");
-	equals(_error->PopMessage(text), true);
-	equals(text, "Something horrible happened 2 times");
-	equals(_error->empty(GlobalError::DEBUG), true);
-	equals(_error->PendingError(), false);
-	equals(_error->Error("%s horrible %s %d times", "Something", "happened", 2), false);
-	equals(_error->PendingError(), true);
-	equals(_error->empty(GlobalError::FATAL), false);
-	_error->Discard();
+   std::string text;
+   EXPECT_FALSE(e.PopMessage(text));
+   EXPECT_TRUE(e.PendingError());
+   EXPECT_EQ("A Notice", text);
+   EXPECT_TRUE(e.PopMessage(text));
+   EXPECT_EQ("Something horrible happened 2 times", text);
+   EXPECT_TRUE(e.empty(GlobalError::DEBUG));
+   EXPECT_FALSE(e.PendingError());
+   EXPECT_FALSE(e.Error("%s horrible %s %d times", "Something", "happened", 2));
+   EXPECT_TRUE(e.PendingError());
+   EXPECT_FALSE(e.empty(GlobalError::FATAL));
+   e.Discard();
 
-	equals(_error->empty(), true);
-	equals(_error->PendingError(), false);
-	equals(_error->Notice("%s Notice", "A"), false);
-	equals(_error->Error("%s horrible %s %d times", "Something", "happened", 2), false);
-	equals(_error->PendingError(), true);
-	equals(_error->empty(GlobalError::NOTICE), false);
-	_error->PushToStack();
-	equals(_error->empty(GlobalError::NOTICE), true);
-	equals(_error->PendingError(), false);
-	equals(_error->Warning("%s Warning", "A"), false);
-	equals(_error->empty(GlobalError::ERROR), true);
-	equals(_error->PendingError(), false);
-	_error->RevertToStack();
-	equals(_error->empty(GlobalError::ERROR), false);
-	equals(_error->PendingError(), true);
-	equals(_error->PopMessage(text), false);
-	equals(_error->PendingError(), true);
-	equals(text, "A Notice");
-	equals(_error->PopMessage(text), true);
-	equals(text, "Something horrible happened 2 times");
-	equals(_error->PendingError(), false);
-	equals(_error->empty(), true);
-
-	equals(_error->Notice("%s Notice", "A"), false);
-	equals(_error->Error("%s horrible %s %d times", "Something", "happened", 2), false);
-	equals(_error->PendingError(), true);
-	equals(_error->empty(GlobalError::NOTICE), false);
-	_error->PushToStack();
-	equals(_error->empty(GlobalError::NOTICE), true);
-	equals(_error->PendingError(), false);
-	equals(_error->Warning("%s Warning", "A"), false);
-	equals(_error->empty(GlobalError::ERROR), true);
-	equals(_error->PendingError(), false);
-	_error->MergeWithStack();
-	equals(_error->empty(GlobalError::ERROR), false);
-	equals(_error->PendingError(), true);
-	equals(_error->PopMessage(text), false);
-	equals(_error->PendingError(), true);
-	equals(text, "A Notice");
-	equals(_error->PopMessage(text), true);
-	equals(text, "Something horrible happened 2 times");
-	equals(_error->PendingError(), false);
-	equals(_error->empty(), false);
-	equals(_error->PopMessage(text), false);
-	equals(text, "A Warning");
-	equals(_error->empty(), true);
-
-	errno = 0;
-	equals(_error->Errno("errno", "%s horrible %s %d times", "Something", "happened", 2), false);
-	equals(_error->empty(), false);
-	equals(_error->PendingError(), true);
-	equals(_error->PopMessage(text), true);
-	equals(_error->PendingError(), false);
-	equals(text, std::string("Something horrible happened 2 times - errno (0: ").append(textOfErrnoZero).append(")"));
-	equals(_error->empty(), true);
+   EXPECT_TRUE(e.empty());
+   EXPECT_FALSE(e.PendingError());
+}
+TEST(GlobalErrorTest,StackPushing)
+{
+   GlobalError e;
+   EXPECT_FALSE(e.Notice("%s Notice", "A"));
+   EXPECT_FALSE(e.Error("%s horrible %s %d times", "Something", "happened", 2));
+   EXPECT_TRUE(e.PendingError());
+   EXPECT_FALSE(e.empty(GlobalError::NOTICE));
+   e.PushToStack();
+   EXPECT_TRUE(e.empty(GlobalError::NOTICE));
+   EXPECT_FALSE(e.PendingError());
+   EXPECT_FALSE(e.Warning("%s Warning", "A"));
+   EXPECT_TRUE(e.empty(GlobalError::ERROR));
+   EXPECT_FALSE(e.PendingError());
+   e.RevertToStack();
+   EXPECT_FALSE(e.empty(GlobalError::ERROR));
+   EXPECT_TRUE(e.PendingError());
 
-	std::string longText;
-	for (size_t i = 0; i < 500; ++i)
-		longText.append("a");
-	equals(_error->Error("%s horrible %s %d times", longText.c_str(), "happened", 2), false);
-	equals(_error->PopMessage(text), true);
-	equals(text, std::string(longText).append(" horrible happened 2 times"));
+   std::string text;
+   EXPECT_FALSE(e.PopMessage(text));
+   EXPECT_TRUE(e.PendingError());
+   EXPECT_EQ("A Notice", text);
+   EXPECT_TRUE(e.PopMessage(text));
+   EXPECT_EQ("Something horrible happened 2 times", text);
+   EXPECT_FALSE(e.PendingError());
+   EXPECT_TRUE(e.empty());
 
-	equals(_error->Errno("errno", "%s horrible %s %d times", longText.c_str(), "happened", 2), false);
-	equals(_error->PopMessage(text), true);
-	equals(text, std::string(longText).append(" horrible happened 2 times - errno (0: ").append(textOfErrnoZero).append(")"));
+   EXPECT_FALSE(e.Notice("%s Notice", "A"));
+   EXPECT_FALSE(e.Error("%s horrible %s %d times", "Something", "happened", 2));
+   EXPECT_TRUE(e.PendingError());
+   EXPECT_FALSE(e.empty(GlobalError::NOTICE));
+   e.PushToStack();
+   EXPECT_TRUE(e.empty(GlobalError::NOTICE));
+   EXPECT_FALSE(e.PendingError());
+   EXPECT_FALSE(e.Warning("%s Warning", "A"));
+   EXPECT_TRUE(e.empty(GlobalError::ERROR));
+   EXPECT_FALSE(e.PendingError());
+   e.MergeWithStack();
+   EXPECT_FALSE(e.empty(GlobalError::ERROR));
+   EXPECT_TRUE(e.PendingError());
+   EXPECT_FALSE(e.PopMessage(text));
+   EXPECT_TRUE(e.PendingError());
+   EXPECT_EQ("A Notice", text);
+   EXPECT_TRUE(e.PopMessage(text));
+   EXPECT_EQ("Something horrible happened 2 times", text);
+   EXPECT_FALSE(e.PendingError());
+   EXPECT_FALSE(e.empty());
+   EXPECT_FALSE(e.PopMessage(text));
+   EXPECT_EQ("A Warning", text);
+   EXPECT_TRUE(e.empty());
+}
+TEST(GlobalErrorTest,Errno)
+{
+   GlobalError e;
+   std::string const textOfErrnoZero(strerror(0));
+   errno = 0;
+   EXPECT_FALSE(e.Errno("errno", "%s horrible %s %d times", "Something", "happened", 2));
+   EXPECT_FALSE(e.empty());
+   EXPECT_TRUE(e.PendingError());
+   std::string text;
+   EXPECT_TRUE(e.PopMessage(text));
+   EXPECT_FALSE(e.PendingError());
+   EXPECT_EQ(std::string("Something horrible happened 2 times - errno (0: ").append(textOfErrnoZero).append(")"), text);
+   EXPECT_TRUE(e.empty());
+}
+TEST(GlobalErrorTest,LongMessage)
+{
+   GlobalError e;
+   std::string const textOfErrnoZero(strerror(0));
+   errno = 0;
+   std::string text, longText;
+   for (size_t i = 0; i < 500; ++i)
+      longText.append("a");
+   EXPECT_FALSE(e.Error("%s horrible %s %d times", longText.c_str(), "happened", 2));
+   EXPECT_TRUE(e.PopMessage(text));
+   EXPECT_EQ(std::string(longText).append(" horrible happened 2 times"), text);
 
-	equals(_error->Warning("Репозиторий не обновлён и будут %d %s", 4, "test"), false);
-	equals(_error->PopMessage(text), false);
-	equals(text, "Репозиторий не обновлён и будут 4 test");
+   EXPECT_FALSE(e.Errno("errno", "%s horrible %s %d times", longText.c_str(), "happened", 2));
+   EXPECT_TRUE(e.PopMessage(text));
+   EXPECT_EQ(std::string(longText).append(" horrible happened 2 times - errno (0: ").append(textOfErrnoZero).append(")"), text);
+}
+TEST(GlobalErrorTest,UTF8Message)
+{
+   GlobalError e;
+   std::string text;
 
-	longText.clear();
-	for (size_t i = 0; i < 50; ++i)
-		longText.append("РезийбёбAZ");
-	equals(_error->Warning("%s", longText.c_str()), false);
-	equals(_error->PopMessage(text), false);
-	equals(text, longText);
+   EXPECT_FALSE(e.Warning("Репозиторий не обновлён и будут %d %s", 4, "test"));
+   EXPECT_FALSE(e.PopMessage(text));
+   EXPECT_EQ("Репозиторий не обновлён и будут 4 test", text);
 
-	return 0;
+   std::string longText;
+   for (size_t i = 0; i < 50; ++i)
+      longText.append("РезийбёбAZ");
+   EXPECT_FALSE(e.Warning("%s", longText.c_str()));
+   EXPECT_FALSE(e.PopMessage(text));
+   EXPECT_EQ(longText, text);
 }

+ 19 - 0
test/libapt/gtest_runner.cc

@@ -0,0 +1,19 @@
+#include <gtest/gtest.h>
+#include <apt-pkg/error.h>
+int main(int argc, char **argv) {
+   ::testing::InitGoogleTest(&argc, argv);
+   int result = RUN_ALL_TESTS();
+   if (_error->empty() == false)
+   {
+      std::cerr << "The test generated the following global messages:" << std::endl;
+      _error->DumpErrors(std::cerr);
+      // messages on the stack can't be right, error out
+      // even if we have no idea where this message came from
+      if (result == 0)
+      {
+	 std::cerr << "All tests successful, but messages were generated, so still a failure!" << std::endl;
+	 return 29;
+      }
+   }
+   return result;
+}

+ 155 - 119
test/libapt/hashsums_test.cc

@@ -11,7 +11,9 @@
 #include <stdlib.h>
 #include <string>
 
-#include "assert.h"
+#include <gtest/gtest.h>
+
+#include "file-helpers.h"
 
 template <class T> void Test(const char *In,const char *Out)
 {
@@ -20,167 +22,201 @@ template <class T> void Test(const char *In,const char *Out)
    equals(Sum.Result().Value(), Out);
 }
 
-template <class T> void TestMill(const char *Out)
+
+
+TEST(HashSumsTest,SummationStrings)
 {
-   T Sum;
+#define EXPECT_SUM(Summation, In, Out) \
+   { \
+      Summation Sum; \
+      Sum.Add(In); \
+      EXPECT_EQ(Sum.Result().Value(), Out) << #Summation << " for '" << In << "'"; \
+   }
+
+   // From  FIPS PUB 180-1
+   EXPECT_SUM(SHA1Summation, "","da39a3ee5e6b4b0d3255bfef95601890afd80709");
+   EXPECT_SUM(SHA1Summation, "abc","a9993e364706816aba3e25717850c26c9cd0d89d");
+   EXPECT_SUM(SHA1Summation, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+	 "84983e441c3bd26ebaae4aa1f95129e5e54670f1");
+
+   // MD5 tests from RFC 1321
+   EXPECT_SUM(MD5Summation, "","d41d8cd98f00b204e9800998ecf8427e");
+   EXPECT_SUM(MD5Summation, "a","0cc175b9c0f1b6a831c399e269772661");
+   EXPECT_SUM(MD5Summation, "abc","900150983cd24fb0d6963f7d28e17f72");
+   EXPECT_SUM(MD5Summation, "message digest","f96b697d7cb7938d525a2f31aaf161d0");
+   EXPECT_SUM(MD5Summation, "abcdefghijklmnopqrstuvwxyz","c3fcd3d76192e4007dfb496cca67e13b");
+   EXPECT_SUM(MD5Summation, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+	 "d174ab98d277d9f5a5611c2c9f419d9f");
+   EXPECT_SUM(MD5Summation, "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+	 "57edf4a22be3c955ac49da2e2107b67a");
 
-   const unsigned char As[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
-   unsigned Count = 1000000;
-   for (; Count != 0;)
+   // SHA-256, From FIPS 180-2
+   EXPECT_SUM(SHA256Summation, "", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
+   EXPECT_SUM(SHA256Summation, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+	 "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1");
+
+   // SHA-512
+   EXPECT_SUM(SHA512Summation, "",
+	 "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce"
+	 "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e");
+   EXPECT_SUM(SHA512Summation, "abc",
+	 "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
+	 "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f");
+
+
+   EXPECT_SUM(MD5Summation, "The quick brown fox jumps over the lazy dog", "9e107d9d372bb6826bd81d3542a419d6");
+   EXPECT_SUM(MD5Summation, "The quick brown fox jumps over the lazy dog.", "e4d909c290d0fb1ca068ffaddf22cbd0");
+   EXPECT_SUM(SHA1Summation, "The quick brown fox jumps over the lazy dog", "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12");
+   EXPECT_SUM(SHA1Summation, "The quick brown fox jumps over the lazy cog", "de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3");
+   EXPECT_SUM(SHA256Summation, "The quick brown fox jumps over the lazy dog", "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592");
+   EXPECT_SUM(SHA256Summation, "The quick brown fox jumps over the lazy dog.", "ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c");
+   EXPECT_SUM(SHA512Summation, "The quick brown fox jumps over the lazy dog", "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb64"
+	 "2e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6");
+   EXPECT_SUM(SHA512Summation, "The quick brown fox jumps over the lazy dog.", "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bb"
+	 "c6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed");
+
+#undef EXPECT_SUM
+}
+TEST(HashSumsTest, Mill)
+{
+   SHA1Summation Sum1;
+
+   const unsigned char As[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+   size_t const AsCount = sizeof(As)/sizeof(As[0]) - 1;
+   size_t Count = 1000000;
+   while (Count != 0)
    {
-      if (Count >= 64)
+      if (Count >= AsCount)
       {
-	 Sum.Add(As,64);
-	 Count -= 64;
+	 Sum1.Add(As, AsCount);
+	 Count -= AsCount;
       }
       else
       {
-	 Sum.Add(As,Count);
+	 Sum1.Add(As,Count);
 	 Count = 0;
       }
    }
 
-   if (stringcasecmp(Sum.Result().Value(), Out) != 0)
-      abort();
+   EXPECT_EQ("34aa973cd4c4daa4f61eeb2bdbad27316534016f", Sum1.Result().Value());
 }
 
-int main(int argc, char** argv)
+static void getSummationString(char const * const type, std::string &sum)
 {
-   if (argc != 6) {
-      std::cout << "Five parameter expected - given " << argc << std::endl;
-      return 100;
-   }
+   /* to compare our result with an independent source we call the specific binaries
+      and read their result back. We do this with a little trick by claiming that the
+      summation is a compressor – and open the 'compressed' file later on directly to
+      read out the summation sum calculated by it */
+   APT::Configuration::Compressor compress(type, ".ext", type, NULL, NULL, 99);
+   std::string name("apt-test-");
+   name.append("hashsums").append(".XXXXXX");
+   char * tempfile = strdup(name.c_str());
+   int tempfile_fd = mkstemp(tempfile);
+   close(tempfile_fd);
+   ASSERT_NE(-1, tempfile_fd);
+
+   FileFd fd;
+   ASSERT_TRUE(fd.Open(tempfile, FileFd::WriteOnly | FileFd::Empty, compress));
+   ASSERT_TRUE(fd.IsOpen());
+   FileFd input(__FILE__, FileFd::ReadOnly);
+   ASSERT_TRUE(input.IsOpen());
+   ASSERT_NE(0, input.FileSize());
+   ASSERT_TRUE(CopyFile(input, fd));
+   ASSERT_TRUE(input.IsOpen());
+   ASSERT_TRUE(fd.IsOpen());
+   ASSERT_FALSE(fd.Failed());
+   input.Close();
+   fd.Close();
+   ASSERT_TRUE(fd.Open(tempfile, FileFd::ReadOnly, FileFd::None));
+   ASSERT_TRUE(fd.IsOpen());
+   ASSERT_NE(0, fd.FileSize());
+   ASSERT_FALSE(fd.Failed());
+   unlink(tempfile);
+   free(tempfile);
+   char readback[2000];
+   unsigned long long actual;
+   ASSERT_TRUE(fd.Read(readback, sizeof(readback)/sizeof(readback[0]), &actual));
+   actual -= 4;
+   readback[actual] = '\0';
+   sum = readback;
+}
+TEST(HashSumsTest, FileBased)
+{
+   std::string summation;
 
-   // test HashSumValue which doesn't calculate but just stores sums
-   {
-   std::string md5sum = argv[2];
-   MD5SumValue md5(md5sum);
-   equals(md5.Value(), md5sum);
-   }
-   {
-   std::string sha1sum = argv[3];
-   SHA1SumValue sha1(sha1sum);
-   equals(sha1.Value(), sha1sum);
-   }
-   {
-   std::string sha2sum = argv[4];
-   SHA256SumValue sha2(sha2sum);
-   equals(sha2.Value(), sha2sum);
-   }
-   {
-   std::string sha2sum = argv[5];
-   SHA512SumValue sha2(sha2sum);
-   equals(sha2.Value(), sha2sum);
-   }
+   getSummationString("md5sum", summation);
+   MD5SumValue md5(summation);
+   EXPECT_EQ(md5.Value(), summation);
 
-   // From  FIPS PUB 180-1
-   Test<SHA1Summation>("","da39a3ee5e6b4b0d3255bfef95601890afd80709");
-   Test<SHA1Summation>("abc","a9993e364706816aba3e25717850c26c9cd0d89d");
-   Test<SHA1Summation>("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
-		       "84983e441c3bd26ebaae4aa1f95129e5e54670f1");
-   TestMill<SHA1Summation>("34aa973cd4c4daa4f61eeb2bdbad27316534016f");
+   getSummationString("sha1sum", summation);
+   SHA1SumValue sha1(summation);
+   EXPECT_EQ(sha1.Value(), summation);
 
-   // MD5 tests from RFC 1321
-   Test<MD5Summation>("","d41d8cd98f00b204e9800998ecf8427e");
-   Test<MD5Summation>("a","0cc175b9c0f1b6a831c399e269772661");
-   Test<MD5Summation>("abc","900150983cd24fb0d6963f7d28e17f72");
-   Test<MD5Summation>("message digest","f96b697d7cb7938d525a2f31aaf161d0");
-   Test<MD5Summation>("abcdefghijklmnopqrstuvwxyz","c3fcd3d76192e4007dfb496cca67e13b");
-   Test<MD5Summation>("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
-		      "d174ab98d277d9f5a5611c2c9f419d9f");
-   Test<MD5Summation>("12345678901234567890123456789012345678901234567890123456789012345678901234567890",
-		      "57edf4a22be3c955ac49da2e2107b67a");
+   getSummationString("sha256sum", summation);
+   SHA256SumValue sha256(summation);
+   EXPECT_EQ(sha256.Value(), summation);
 
-   // SHA-256, From FIPS 180-2
-   Test<SHA256Summation>("", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
-   Test<SHA256Summation>("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
-			 "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1");
+   getSummationString("sha512sum", summation);
+   SHA512SumValue sha512(summation);
+   EXPECT_EQ(sha512.Value(), summation);
+
+   FileFd fd(__FILE__, FileFd::ReadOnly);
+   EXPECT_TRUE(fd.IsOpen());
 
-   // SHA-512
-   Test<SHA512Summation>("",
-	"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce"
-	"47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e");
-   Test<SHA512Summation>(
-      "abc",
-      "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
-      "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f");
-
-
-   Test<MD5Summation>("The quick brown fox jumps over the lazy dog", "9e107d9d372bb6826bd81d3542a419d6");
-   Test<MD5Summation>("The quick brown fox jumps over the lazy dog.", "e4d909c290d0fb1ca068ffaddf22cbd0");
-   Test<SHA1Summation>("The quick brown fox jumps over the lazy dog", "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12");
-   Test<SHA1Summation>("The quick brown fox jumps over the lazy cog", "de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3");
-   Test<SHA256Summation>("The quick brown fox jumps over the lazy dog", "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592");
-   Test<SHA256Summation>("The quick brown fox jumps over the lazy dog.", "ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c");
-   Test<SHA512Summation>("The quick brown fox jumps over the lazy dog", "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb64"
-									"2e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6");
-   Test<SHA512Summation>("The quick brown fox jumps over the lazy dog.", "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bb"
-									 "c6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed");
-
-   FileFd fd(argv[1], FileFd::ReadOnly);
-   if (fd.IsOpen() == false) {
-      std::cerr << "Can't open file for 1. testing: " << argv[1] << std::endl;
-      return 1;
-   }
    {
-   Hashes hashes;
-   hashes.AddFD(fd.Fd());
-   equals(argv[2], hashes.MD5.Result().Value());
-   equals(argv[3], hashes.SHA1.Result().Value());
-   equals(argv[4], hashes.SHA256.Result().Value());
-   equals(argv[5], hashes.SHA512.Result().Value());
+      Hashes hashes;
+      hashes.AddFD(fd.Fd());
+      EXPECT_EQ(md5.Value(), hashes.MD5.Result().Value());
+      EXPECT_EQ(sha1.Value(), hashes.SHA1.Result().Value());
+      EXPECT_EQ(sha256.Value(), hashes.SHA256.Result().Value());
+      EXPECT_EQ(sha512.Value(), hashes.SHA512.Result().Value());
    }
    unsigned long sz = fd.FileSize();
    fd.Seek(0);
    {
-   Hashes hashes;
-   hashes.AddFD(fd.Fd(), sz);
-   equals(argv[2], hashes.MD5.Result().Value());
-   equals(argv[3], hashes.SHA1.Result().Value());
-   equals(argv[4], hashes.SHA256.Result().Value());
-   equals(argv[5], hashes.SHA512.Result().Value());
+      Hashes hashes;
+      hashes.AddFD(fd.Fd(), sz);
+      EXPECT_EQ(md5.Value(), hashes.MD5.Result().Value());
+      EXPECT_EQ(sha1.Value(), hashes.SHA1.Result().Value());
+      EXPECT_EQ(sha256.Value(), hashes.SHA256.Result().Value());
+      EXPECT_EQ(sha512.Value(), hashes.SHA512.Result().Value());
    }
    fd.Seek(0);
    {
-   MD5Summation md5;
-   md5.AddFD(fd.Fd());
-   equals(argv[2], md5.Result().Value());
+      MD5Summation MD5;
+      MD5.AddFD(fd.Fd());
+      EXPECT_EQ(md5.Value(), MD5.Result().Value());
    }
    fd.Seek(0);
    {
-   SHA1Summation sha1;
-   sha1.AddFD(fd.Fd());
-   equals(argv[3], sha1.Result().Value());
+      SHA1Summation SHA1;
+      SHA1.AddFD(fd.Fd());
+      EXPECT_EQ(sha1.Value(), SHA1.Result().Value());
    }
    fd.Seek(0);
    {
-   SHA256Summation sha2;
-   sha2.AddFD(fd.Fd());
-   equals(argv[4], sha2.Result().Value());
+      SHA256Summation SHA2;
+      SHA2.AddFD(fd.Fd());
+      EXPECT_EQ(sha256.Value(), SHA2.Result().Value());
    }
    fd.Seek(0);
    {
-   SHA512Summation sha2;
-   sha2.AddFD(fd.Fd());
-   equals(argv[5], sha2.Result().Value());
+      SHA512Summation SHA2;
+      SHA2.AddFD(fd.Fd());
+      EXPECT_EQ(sha512.Value(), SHA2.Result().Value());
    }
    fd.Close();
 
-   // test HashString code
    {
-   HashString sha2("SHA256", argv[4]);
-   equals(sha2.VerifyFile(argv[1]), true);
+      HashString sha2("SHA256", sha256.Value());
+      EXPECT_TRUE(sha2.VerifyFile(__FILE__));
    }
    {
-   HashString sha2("SHA512", argv[5]);
-   equals(sha2.VerifyFile(argv[1]), true);
+      HashString sha2("SHA512", sha512.Value());
+      EXPECT_TRUE(sha2.VerifyFile(__FILE__));
    }
    {
-   HashString sha2("SHA256:" + std::string(argv[4]));
-   equals(sha2.VerifyFile(argv[1]), true);
+      HashString sha2("SHA256:" + sha256.Value());
+      EXPECT_TRUE(sha2.VerifyFile(__FILE__));
    }
-
-   return 0;
 }
-
-

+ 38 - 35
test/libapt/indexcopytosourcelist_test.cc

@@ -7,30 +7,35 @@
 #include <string>
 #include <stdio.h>
 
-#include "assert.h"
+#include <gtest/gtest.h>
 
 class NoCopy : public IndexCopy {
-public:
-   std::string ConvertToSourceList(std::string CD,std::string Path) {
-      IndexCopy::ConvertToSourceList(CD, Path);
-      return Path;
-   }
-   bool GetFile(std::string &/*Filename*/, unsigned long long &/*Size*/) { return false; }
-   bool RewriteEntry(FILE * /*Target*/, std::string /*File*/) { return false; }
-   const char *GetFileName() { return NULL; }
-   const char *Type() { return NULL; }
+   public:
+      std::string ConvertToSourceList(std::string CD,std::string Path) {
+	 IndexCopy::ConvertToSourceList(CD, Path);
+	 return Path;
+      }
+      bool GetFile(std::string &/*Filename*/, unsigned long long &/*Size*/) { return false; }
+      bool RewriteEntry(FILE * /*Target*/, std::string /*File*/) { return false; }
+      const char *GetFileName() { return NULL; }
+      const char *Type() { return NULL; }
 
 };
 
-int main() {
+TEST(IndexCopyTest, ConvertToSourceList)
+{
    NoCopy ic;
    std::string const CD("/media/cdrom/");
 
    char const * Releases[] = { "unstable", "wheezy-updates", NULL };
    char const * Components[] = { "main", "non-free", NULL };
 
-   for (char const ** Release = Releases; *Release != NULL; ++Release) {
-      for (char const ** Component = Components; *Component != NULL; ++Component) {
+   for (char const ** Release = Releases; *Release != NULL; ++Release)
+   {
+      SCOPED_TRACE(std::string("Release ") + *Release);
+      for (char const ** Component = Components; *Component != NULL; ++Component)
+      {
+	 SCOPED_TRACE(std::string("Component ") + *Component);
 	 std::string const Path = std::string("dists/") + *Release + "/" + *Component + "/";
 	 std::string const Binary = Path + "binary-";
 	 std::string const A = Binary + "armel/";
@@ -41,49 +46,47 @@ int main() {
 
 	 _config->Clear("APT");
 	 APT::Configuration::getArchitectures(false);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + A), A);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + B), B);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + C), C);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + S), List);
+	 EXPECT_EQ(A, ic.ConvertToSourceList("/media/cdrom/", CD + A));
+	 EXPECT_EQ(B, ic.ConvertToSourceList("/media/cdrom/", CD + B));
+	 EXPECT_EQ(C, ic.ConvertToSourceList("/media/cdrom/", CD + C));
+	 EXPECT_EQ(List, ic.ConvertToSourceList("/media/cdrom/", CD + S));
 
 	 _config->Clear("APT");
 	 _config->Set("APT::Architecture", "mips");
 	 _config->Set("APT::Architectures::", "mips");
 	 APT::Configuration::getArchitectures(false);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + A), A);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + B), List);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + C), C);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + S), List);
+	 EXPECT_EQ(A, ic.ConvertToSourceList("/media/cdrom/", CD + A));
+	 EXPECT_EQ(List, ic.ConvertToSourceList("/media/cdrom/", CD + B));
+	 EXPECT_EQ(C, ic.ConvertToSourceList("/media/cdrom/", CD + C));
+	 EXPECT_EQ(List, ic.ConvertToSourceList("/media/cdrom/", CD + S));
 
 	 _config->Clear("APT");
 	 _config->Set("APT::Architecture", "kfreebsd-mips");
 	 _config->Set("APT::Architectures::", "kfreebsd-mips");
 	 APT::Configuration::getArchitectures(false);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + A), A);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + B), B);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + C), List);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + S), List);
+	 EXPECT_EQ(A, ic.ConvertToSourceList("/media/cdrom/", CD + A));
+	 EXPECT_EQ(B, ic.ConvertToSourceList("/media/cdrom/", CD + B));
+	 EXPECT_EQ(List, ic.ConvertToSourceList("/media/cdrom/", CD + C));
+	 EXPECT_EQ(List, ic.ConvertToSourceList("/media/cdrom/", CD + S));
 
 	 _config->Clear("APT");
 	 _config->Set("APT::Architecture", "armel");
 	 _config->Set("APT::Architectures::", "armel");
 	 APT::Configuration::getArchitectures(false);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + A), List);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + B), B);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + C), C);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + S), List);
+	 EXPECT_EQ(List, ic.ConvertToSourceList("/media/cdrom/", CD + A));
+	 EXPECT_EQ(B, ic.ConvertToSourceList("/media/cdrom/", CD + B));
+	 EXPECT_EQ(C, ic.ConvertToSourceList("/media/cdrom/", CD + C));
+	 EXPECT_EQ(List, ic.ConvertToSourceList("/media/cdrom/", CD + S));
 
 	 _config->Clear("APT");
 	 _config->Set("APT::Architecture", "armel");
 	 _config->Set("APT::Architectures::", "armel");
 	 _config->Set("APT::Architectures::", "mips");
 	 APT::Configuration::getArchitectures(false);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + A), List);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + B), List);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + C), C);
-	 equals(ic.ConvertToSourceList("/media/cdrom/", CD + S), List);
+	 EXPECT_EQ(List, ic.ConvertToSourceList("/media/cdrom/", CD + A));
+	 EXPECT_EQ(List, ic.ConvertToSourceList("/media/cdrom/", CD + B));
+	 EXPECT_EQ(C, ic.ConvertToSourceList("/media/cdrom/", CD + C));
+	 EXPECT_EQ(List, ic.ConvertToSourceList("/media/cdrom/", CD + S));
       }
    }
-
-   return 0;
 }

+ 8 - 18
test/libapt/install_progress_test.cc

@@ -4,27 +4,17 @@
 
 #include <string>
 
-#include "assert.h"
+#include <gtest/gtest.h>
 
-int main() {
+TEST(InstallProgressTest, FancyGetTextProgressStr)
+{
    APT::Progress::PackageManagerFancy p;
-   std::string s;   
 
-   s= p.GetTextProgressStr(0.5, 60);
-   equals(s.size(), 60);
-   
-   s= p.GetTextProgressStr(0.5, 4);
-   equals(s, "[#.]");
-
-   s= p.GetTextProgressStr(0.1, 12);
-   equals(s, "[#.........]");
-   
-   s= p.GetTextProgressStr(0.9, 12);
-   equals(s, "[#########.]");
+   EXPECT_EQ(60, p.GetTextProgressStr(0.5, 60).size());
+   EXPECT_EQ("[#.]", p.GetTextProgressStr(0.5, 4));
+   EXPECT_EQ("[#.........]", p.GetTextProgressStr(0.1, 12));
+   EXPECT_EQ("[#########.]", p.GetTextProgressStr(0.9, 12));
 
    // deal with incorrect inputs gracefully (or should we die instead?)
-   s= p.GetTextProgressStr(-999, 12);
-   equals(s, "");
-
-   return 0;
+   EXPECT_EQ("", p.GetTextProgressStr(-999, 12));
 }

+ 63 - 121
test/libapt/makefile

@@ -8,124 +8,66 @@ APT_DOMAIN=none
 include ../../buildlib/defaults.mak
 
 .PHONY: test
-test:
-	./run-tests
-
-# Program for testing getLanguageCode
-PROGRAM = getLanguages${BASENAME}
-SLIBS = -lapt-pkg
-SOURCE = getlanguages_test.cc
-include $(PROGRAM_H)
-
-PROGRAM = getArchitectures${BASENAME}
-SLIBS = -lapt-pkg
-SOURCE = getarchitectures_test.cc
-include $(PROGRAM_H)
-
-# Program for testing ParseDepends
-PROGRAM = ParseDepends${BASENAME}
-SLIBS = -lapt-pkg
-SOURCE = parsedepends_test.cc
-include $(PROGRAM_H)
-
-# Program for testing GetListOfFilesInDir
-PROGRAM = GetListOfFilesInDir${BASENAME}
-SLIBS = -lapt-pkg
-SOURCE = getlistoffilesindir_test.cc
-include $(PROGRAM_H)
-
-# Program for testing CommandLine reconstruction
-PROGRAM = Commandline${BASENAME}
-SLIBS = -lapt-pkg
-SOURCE = commandline_test.cc
-include $(PROGRAM_H)
-
-# Program for testing CommandLine reconstruction
-PROGRAM = CommandlineAsString${BASENAME}
-SLIBS = -lapt-pkg
-SOURCE = commandlineasstring_test.cc
-include $(PROGRAM_H)
-
-# Program for testing debians version comparing
-PROGRAM = CompareVersion${BASENAME}
-SLIBS = -lapt-pkg
-SOURCE = compareversion_test.cc
-include $(PROGRAM_H)
-
-# test the GlobalError stack class
-PROGRAM = GlobalError${BASENAME}
-SLIBS = -lapt-pkg
-SOURCE = globalerror_test.cc
-include $(PROGRAM_H)
-
-# test the different Hashsum classes
-PROGRAM = HashSums${BASENAME}
-SLIBS = -lapt-pkg
-SOURCE = hashsums_test.cc
-include $(PROGRAM_H)
-
-# test the strutils stuff
-PROGRAM = StrUtil${BASENAME}
-SLIBS = -lapt-pkg
-SOURCE = strutil_test.cc
-include $(PROGRAM_H)
-
-# test the URI parsing stuff
-PROGRAM = URI${BASENAME}
-SLIBS = -lapt-pkg
-SOURCE = uri_test.cc
-include $(PROGRAM_H)
-
-# test the Configuration class
-PROGRAM = Configuration${BASENAME}
-SLIBS = -lapt-pkg
-SOURCE = configuration_test.cc
-include $(PROGRAM_H)
-
-# test cdroms core FindPackages
-PROGRAM = CdromFindPackages${BASENAME}
-SLIBS = -lapt-pkg
-SOURCE = cdromfindpackages_test.cc
-include $(PROGRAM_H)
-
-# test cdroms index reduction for source.list
-PROGRAM = CdromReduceSourceList${BASENAME}
-SLIBS = -lapt-pkg
-SOURCE = cdromreducesourcelist_test.cc
-include $(PROGRAM_H)
-
-# test cdroms FindMountPointForDevice for udev autodetection
-PROGRAM = CdromFindMountPointForDevice${BASENAME}
-SLIBS = -lapt-pkg
-SOURCE = cdromfindmountpointfordevice_test.cc
-include $(PROGRAM_H)
-
-# test IndexCopy::ConvertToSourceList
-PROGRAM = IndexCopyToSourceList${BASENAME}
-SLIBS = -lapt-pkg
-SOURCE = indexcopytosourcelist_test.cc
-
-# test fileutls
-PROGRAM = FileUtl${BASENAME}
-SLIBS = -lapt-pkg 
-SOURCE = fileutl_test.cc
-include $(PROGRAM_H)
-
-# test tagfile
-PROGRAM = PkgTagFile${BASENAME}
-SLIBS = -lapt-pkg
-SOURCE = tagfile_test.cc
-include $(PROGRAM_H)
-
-# test sourcelist
-PROGRAM = SourceList${BASENAME}
-SLIBS = -lapt-pkg
-SOURCE = sourcelist_test.cc
-include $(PROGRAM_H)
-
-# test install-progress
-PROGRAM = InstallProgress${BASENAME}
-SLIBS = -lapt-pkg
-SOURCE = install_progress_test.cc
-include $(PROGRAM_H)
-
+test: $(BIN)/gtest$(BASENAME)
+	MALLOC_PERTURB_=21 MALLOC_CHECK_=2 LD_LIBRARY_PATH=$(LIB) $(BIN)/gtest$(BASENAME)
+
+$(BIN)/gtest$(BASENAME): $(LIB)/gtest.a
+
+PROGRAM = gtest${BASENAME}
+SLIBS = -lapt-pkg -pthread $(LIB)/gtest.a
+LIB_MAKES = apt-pkg/makefile
+SOURCE = gtest_runner.cc $(wildcard *-helpers.cc *_test.cc)
+include $(PROGRAM_H)
+
+
+MKDIRS += $(OBJ) $(LIB)
+LOCAL=gtest
+SOURCE=gtest-all
+gtest-OBJS := $(addprefix $(OBJ)/,$(addsuffix .o,$(SOURCE)))
+
+# The rest of the file is based on the example found in
+# /usr/share/doc/libgtest-dev/examples/make/Makefile
+GTEST_DIR = /usr/src/gtest
+
+# Flags passed to the preprocessor.
+# Set Google Test's header directory as a system directory, such that
+# the compiler doesn't generate warnings in Google Test headers.
+CPPFLAGS += -isystem $(GTEST_DIR)/include
+
+# Flags passed to the C++ compiler.
+CXXFLAGS += -pthread
+# disable some flags for gtest again
+CXXFLAGS+= -Wno-missing-declarations
+CXXFLAGS+= -Wno-missing-field-initializers
+CXXFLAGS+= -Wno-suggest-attribute=pure -Wno-suggest-attribute=const -Wno-suggest-attribute=noreturn
+
+# All Google Test headers.  Usually you shouldn't change this definition.
+GTEST_HEADERS = /usr/include/gtest/*.h \
+                /usr/include/gtest/internal/*.h
+
+# House-keeping build targets.
+.PHONY: clean/gtest veryclean/gtest
+clean: clean/gtest
+clean/gtest:
+	rm -f $(gtest-OBJS)
+veryclean: veryclean/gtest
+veryclean/gtest: clean/gtest
+	rm -f $(LIB)/gtest.a
+
+# Usually you shouldn't tweak such internal variables, indicated by a
+# trailing _.
+GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
+
+# Builds gtest.a
+# For simplicity and to avoid depending on Google Test's
+# implementation details, the dependencies specified below are
+# conservative and not optimized.  This is fine as Google Test
+# compiles fast and for ordinary users its source rarely changes.
+$(gtest-OBJS): $(GTEST_SRCS_)
+	echo Compiling $@
+	$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c -o $@ $(GTEST_DIR)/src/$(notdir $(basename $@)).cc
+
+$(LIB)/gtest.a: $(OBJ)/gtest-all.o
+	echo Building static library $@
+	-rm -f $@
+	$(AR) $(ARFLAGS) $@ $^

+ 233 - 225
test/libapt/parsedepends_test.cc

@@ -7,230 +7,238 @@
 #include <string.h>
 #include <string>
 
-#include "assert.h"
-
-int main() {
-	std::string Package;
-	std::string Version;
-	unsigned int Op = 5;
-	unsigned int Null = 0;
-	bool StripMultiArch = true;
-	bool ParseArchFlags = false;
-	bool ParseRestrictionsList = false;
-	_config->Set("APT::Architecture","amd64");
-	_config->Set("APT::Build-Profiles","stage1");
-
-	const char* Depends =
-		"debhelper:any (>= 5.0), "
-		"libdb-dev:any, "
-		"gettext:native (<= 0.12), "
-		"libcurl4-gnutls-dev:native | libcurl3-gnutls-dev (>> 7.15.5), "
-		"debiandoc-sgml, "
-		"apt (>= 0.7.25), "
-		"not-for-me [ !amd64 ], "
-		"only-for-me [ amd64 ], "
-		"any-for-me [ any ], "
-		"not-for-darwin [ !darwin-any ], "
-		"cpu-for-me [ any-amd64 ], "
-		"os-for-me [ linux-any ], "
-		"cpu-not-for-me [ any-armel ], "
-		"os-not-for-me [ kfreebsd-any ], "
-		"not-in-stage1 <!profile.stage1>, "
-		"not-in-stage1-or-nodoc <!profile.nodoc !profile.stage1>, "
-		"only-in-stage1 <unknown.unknown profile.stage1>, "
-		"overlord-dev:any (= 7.15.3~) | overlord-dev:native (>> 7.15.5), "
-	;
-
-	unsigned short runner = 0;
+#include <gtest/gtest.h>
+
+static void parseDependency(bool const StripMultiArch,  bool const ParseArchFlags, bool const ParseRestrictionsList)
+{
+   std::string Package;
+   std::string Version;
+   unsigned int Op = 5;
+   unsigned int Null = 0;
+   _config->Set("APT::Architecture","amd64");
+   _config->Set("APT::Build-Profiles","stage1");
+
+   const char* Depends =
+      "debhelper:any (>= 5.0), "
+      "libdb-dev:any, "
+      "gettext:native (<= 0.12), "
+      "libcurl4-gnutls-dev:native | libcurl3-gnutls-dev (>> 7.15.5), "
+      "debiandoc-sgml, "
+      "apt (>= 0.7.25), "
+      "not-for-me [ !amd64 ], "
+      "only-for-me [ amd64 ], "
+      "any-for-me [ any ], "
+      "not-for-darwin [ !darwin-any ], "
+      "cpu-for-me [ any-amd64 ], "
+      "os-for-me [ linux-any ], "
+      "cpu-not-for-me [ any-armel ], "
+      "os-not-for-me [ kfreebsd-any ], "
+      "not-in-stage1 <!profile.stage1>, "
+      "not-in-stage1-or-nodoc <!profile.nodoc !profile.stage1>, "
+      "only-in-stage1 <unknown.unknown profile.stage1>, "
+      "overlord-dev:any (= 7.15.3~) | overlord-dev:native (>> 7.15.5), "
+      ;
+
+   // Stripping MultiArch is currently the default setting to not confuse
+   // non-MultiArch capable users of the library with "strange" extensions.
+   const char* Start = Depends;
+   const char* End = Depends + strlen(Depends);
+
+   Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+   if (StripMultiArch == true)
+      EXPECT_EQ("debhelper", Package);
+   else
+      EXPECT_EQ("debhelper:any", Package);
+   EXPECT_EQ("5.0", Version);
+   EXPECT_EQ(Null | pkgCache::Dep::GreaterEq, Op);
+
+   Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+   if (StripMultiArch == true)
+      EXPECT_EQ("libdb-dev", Package);
+   else
+      EXPECT_EQ("libdb-dev:any", Package);
+   EXPECT_EQ("", Version);
+   EXPECT_EQ(Null | pkgCache::Dep::NoOp, Op);
+
+   Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+   if (StripMultiArch == true)
+      EXPECT_EQ("gettext", Package);
+   else
+      EXPECT_EQ("gettext:native", Package);
+   EXPECT_EQ("0.12", Version);
+   EXPECT_EQ(Null | pkgCache::Dep::LessEq, Op);
+
+   Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+   if (StripMultiArch == true)
+      EXPECT_EQ("libcurl4-gnutls-dev", Package);
+   else
+      EXPECT_EQ("libcurl4-gnutls-dev:native", Package);
+   EXPECT_EQ("", Version);
+   EXPECT_EQ(Null | pkgCache::Dep::Or, Op);
+
+   Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+   EXPECT_EQ("libcurl3-gnutls-dev", Package);
+   EXPECT_EQ("7.15.5", Version);
+   EXPECT_EQ(Null | pkgCache::Dep::Greater, Op);
+
+   Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+   EXPECT_EQ("debiandoc-sgml", Package);
+   EXPECT_EQ("", Version);
+   EXPECT_EQ(Null | pkgCache::Dep::NoOp, Op);
+
+   Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+   EXPECT_EQ("apt", Package);
+   EXPECT_EQ("0.7.25", Version);
+   EXPECT_EQ(Null | pkgCache::Dep::GreaterEq, Op);
+
+   if (ParseArchFlags == true) {
+      Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+      EXPECT_EQ("", Package); // not-for-me
+   } else {
+      EXPECT_EQ(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
+      Start = strstr(Start, ",");
+      Start++;
+   }
+
+   if (ParseArchFlags == true) {
+      Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+      EXPECT_EQ("only-for-me", Package);
+      EXPECT_EQ("", Version);
+      EXPECT_EQ(Null | pkgCache::Dep::NoOp, Op);
+   } else {
+      EXPECT_EQ(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
+      Start = strstr(Start, ",");
+      Start++;
+   }
+
+   if (ParseArchFlags == true) {
+      Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+      EXPECT_EQ("any-for-me", Package);
+      EXPECT_EQ("", Version);
+      EXPECT_EQ(Null | pkgCache::Dep::NoOp, Op);
+   } else {
+      EXPECT_EQ(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
+      Start = strstr(Start, ",");
+      Start++;
+   }
+
+   if (ParseArchFlags == true) {
+      Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+      EXPECT_EQ("not-for-darwin", Package);
+      EXPECT_EQ("", Version);
+      EXPECT_EQ(Null | pkgCache::Dep::NoOp, Op);
+   } else {
+      EXPECT_EQ(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
+      Start = strstr(Start, ",");
+      Start++;
+   }
+
+   if (ParseArchFlags == true) {
+      Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+      EXPECT_EQ("cpu-for-me", Package);
+      EXPECT_EQ("", Version);
+      EXPECT_EQ(Null | pkgCache::Dep::NoOp, Op);
+   } else {
+      EXPECT_EQ(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
+      Start = strstr(Start, ",");
+      Start++;
+   }
+
+   if (ParseArchFlags == true) {
+      Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+      EXPECT_EQ("os-for-me", Package);
+      EXPECT_EQ("", Version);
+      EXPECT_EQ(Null | pkgCache::Dep::NoOp, Op);
+   } else {
+      EXPECT_EQ(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
+      Start = strstr(Start, ",");
+      Start++;
+   }
+
+   if (ParseArchFlags == true) {
+      Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+      EXPECT_EQ("", Package); // cpu-not-for-me
+   } else {
+      EXPECT_EQ(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
+      Start = strstr(Start, ",");
+      Start++;
+   }
+
+   if (ParseArchFlags == true) {
+      Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+      EXPECT_EQ("", Package); // os-not-for-me
+   } else {
+      EXPECT_EQ(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
+      Start = strstr(Start, ",");
+      Start++;
+   }
+
+   if (ParseRestrictionsList == true) {
+      Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+      EXPECT_EQ("", Package); // not-in-stage1
+   } else {
+      EXPECT_EQ(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
+      Start = strstr(Start, ",");
+      Start++;
+   }
+
+   if (ParseRestrictionsList == true) {
+      Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+      EXPECT_EQ("", Package); // not-in-stage1-or-in-nodoc
+   } else {
+      EXPECT_EQ(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
+      Start = strstr(Start, ",");
+      Start++;
+   }
+
+   if (ParseRestrictionsList == true) {
+      Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+      EXPECT_EQ("only-in-stage1", Package);
+   } else {
+      EXPECT_EQ(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
+      Start = strstr(Start, ",");
+      Start++;
+   }
+
+   Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+   if (StripMultiArch == true)
+      EXPECT_EQ("overlord-dev", Package);
+   else
+      EXPECT_EQ("overlord-dev:any", Package);
+   EXPECT_EQ("7.15.3~", Version);
+   EXPECT_EQ(Null | pkgCache::Dep::Equals | pkgCache::Dep::Or, Op);
+
+   debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+   if (StripMultiArch == true)
+      EXPECT_EQ("overlord-dev", Package);
+   else
+      EXPECT_EQ("overlord-dev:native", Package);
+   EXPECT_EQ("7.15.5", Version);
+   EXPECT_EQ(Null | pkgCache::Dep::Greater, Op);
+}
+
+// FIXME: This testcase is too big/complex
+TEST(ParseDependsTest, Everything)
+{
+   bool StripMultiArch = true;
+   bool ParseArchFlags = false;
+   bool ParseRestrictionsList = false;
+   unsigned short runner = 0;
+
 test:
-// 	std::clog << (StripMultiArch ? "NO-Multi" : "Multi") << " " << (ParseArchFlags ? "Flags" : "NO-Flags") << std::endl;
-
-	// Stripping MultiArch is currently the default setting to not confuse
-	// non-MultiArch capable users of the library with "strange" extensions.
-	const char* Start = Depends;
-	const char* End = Depends + strlen(Depends);
-
-	Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-	if (StripMultiArch == true)
-		equals("debhelper", Package);
-	else
-		equals("debhelper:any", Package);
-	equals("5.0", Version);
-	equals(Null | pkgCache::Dep::GreaterEq, Op);
-
-	Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-	if (StripMultiArch == true)
-		equals("libdb-dev", Package);
-	else
-		equals("libdb-dev:any", Package);
-	equals("", Version);
-	equals(Null | pkgCache::Dep::NoOp, Op);
-
-	Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-	if (StripMultiArch == true)
-		equals("gettext", Package);
-	else
-		equals("gettext:native", Package);
-	equals("0.12", Version);
-	equals(Null | pkgCache::Dep::LessEq, Op);
-
-	Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-	if (StripMultiArch == true)
-		equals("libcurl4-gnutls-dev", Package);
-	else
-		equals("libcurl4-gnutls-dev:native", Package);
-	equals("", Version);
-	equals(Null | pkgCache::Dep::Or, Op);
-
-	Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-	equals("libcurl3-gnutls-dev", Package);
-	equals("7.15.5", Version);
-	equals(Null | pkgCache::Dep::Greater, Op);
-
-	Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-	equals("debiandoc-sgml", Package);
-	equals("", Version);
-	equals(Null | pkgCache::Dep::NoOp, Op);
-
-	Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-	equals("apt", Package);
-	equals("0.7.25", Version);
-	equals(Null | pkgCache::Dep::GreaterEq, Op);
-
-	if (ParseArchFlags == true) {
-		Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-		equals("", Package); // not-for-me
-	} else {
-		equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
-		Start = strstr(Start, ",");
-		Start++;
-	}
-
-	if (ParseArchFlags == true) {
-		Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-		equals("only-for-me", Package);
-		equals("", Version);
-		equals(Null | pkgCache::Dep::NoOp, Op);
-	} else {
-		equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
-		Start = strstr(Start, ",");
-		Start++;
-	}
-
-	if (ParseArchFlags == true) {
-		Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-		equals("any-for-me", Package);
-		equals("", Version);
-		equals(Null | pkgCache::Dep::NoOp, Op);
-	} else {
-		equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
-		Start = strstr(Start, ",");
-		Start++;
-	}
-
-	if (ParseArchFlags == true) {
-		Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-		equals("not-for-darwin", Package);
-		equals("", Version);
-		equals(Null | pkgCache::Dep::NoOp, Op);
-	} else {
-		equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
-		Start = strstr(Start, ",");
-		Start++;
-	}
-
-	if (ParseArchFlags == true) {
-		Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-		equals("cpu-for-me", Package);
-		equals("", Version);
-		equals(Null | pkgCache::Dep::NoOp, Op);
-	} else {
-		equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
-		Start = strstr(Start, ",");
-		Start++;
-	}
-
-	if (ParseArchFlags == true) {
-		Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-		equals("os-for-me", Package);
-		equals("", Version);
-		equals(Null | pkgCache::Dep::NoOp, Op);
-	} else {
-		equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
-		Start = strstr(Start, ",");
-		Start++;
-	}
-
-	if (ParseArchFlags == true) {
-		Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-		equals("", Package); // cpu-not-for-me
-	} else {
-		equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
-		Start = strstr(Start, ",");
-		Start++;
-	}
-
-	if (ParseArchFlags == true) {
-		Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-		equals("", Package); // os-not-for-me
-	} else {
-		equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
-		Start = strstr(Start, ",");
-		Start++;
-	}
-
-	if (ParseRestrictionsList == true) {
-		Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-		equals("", Package); // not-in-stage1
-	} else {
-		equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
-		Start = strstr(Start, ",");
-		Start++;
-	}
-
-	if (ParseRestrictionsList == true) {
-		Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-		equals("", Package); // not-in-stage1-or-in-nodoc
-	} else {
-		equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
-		Start = strstr(Start, ",");
-		Start++;
-	}
-
-	if (ParseRestrictionsList == true) {
-		Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-		equals("only-in-stage1", Package);
-	} else {
-		equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
-		Start = strstr(Start, ",");
-		Start++;
-	}
-
-	Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-	if (StripMultiArch == true)
-		equals("overlord-dev", Package);
-	else
-		equals("overlord-dev:any", Package);
-	equals("7.15.3~", Version);
-	equals(Null | pkgCache::Dep::Equals | pkgCache::Dep::Or, Op);
-
-	debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
-	if (StripMultiArch == true)
-		equals("overlord-dev", Package);
-	else
-		equals("overlord-dev:native", Package);
-	equals("7.15.5", Version);
-	equals(Null | pkgCache::Dep::Greater, Op);
-
-	if (StripMultiArch == false)
-		if (ParseArchFlags == false)
-			ParseRestrictionsList = !ParseRestrictionsList;
-		ParseArchFlags = !ParseArchFlags;
-	StripMultiArch = !StripMultiArch;
-
-	runner++;
-	if (runner < 8)
-		goto test; // this is the prove: tests are really evil ;)
-
-	return 0;
+   {
+      SCOPED_TRACE(std::string("StripMultiArch: ") + (StripMultiArch ? "true" : "false"));
+      SCOPED_TRACE(std::string("ParseArchFlags: ") + (ParseArchFlags ? "true" : "false"));
+      SCOPED_TRACE(std::string("ParseRestrictionsList: ") + (ParseRestrictionsList ? "true" : "false"));
+      parseDependency(StripMultiArch, ParseArchFlags, ParseRestrictionsList);
+   }
+   if (StripMultiArch == false)
+      if (ParseArchFlags == false)
+	 ParseRestrictionsList = !ParseRestrictionsList;
+   ParseArchFlags = !ParseArchFlags;
+   StripMultiArch = !StripMultiArch;
+
+   runner++;
+   if (runner < 8)
+      goto test; // this is the prove: tests are really evil ;)
 }

File diff suppressed because it is too large
+ 0 - 135
test/libapt/run-tests


+ 16 - 33
test/libapt/sourcelist_test.cc

@@ -1,6 +1,5 @@
 #include <config.h>
 
-#include <apt-pkg/configuration.h>
 #include <apt-pkg/sourcelist.h>
 #include <apt-pkg/fileutl.h>
 
@@ -9,26 +8,20 @@
 #include <string.h>
 #include <unistd.h>
 
-#include "assert.h"
+#include <gtest/gtest.h>
 
-char *tempfile = NULL;
-int tempfile_fd = -1;
+#include "file-helpers.h"
 
-static void remove_tmpfile(void)
-{
-   if (tempfile_fd > 0)
-      close(tempfile_fd);
-   if (tempfile != NULL) {
-      unlink(tempfile);
-      free(tempfile);
-   }
-}
+class SourceList : public pkgSourceList {
+   public:
+      using pkgSourceList::ParseFileDeb822;
+};
 
-int main()
+TEST(SourceListTest,ParseFileDeb822)
 {
-  _config->Set("APT::Sources::Use-Deb822", true);
-
-   const char contents[] = ""
+   FileFd fd;
+   char * tempfile;
+   createTemporaryFile("parsefiledeb822", fd, &tempfile,
       "Types: deb\n"
       "URIs: http://ftp.debian.org/debian\n"
       "Suites: stable\n"
@@ -39,22 +32,12 @@ int main()
       "Types: deb\n"
       "URIs: http://ftp.debian.org/debian\n"
       "Suites: unstable\n"
-      "Sections: main non-free\n"
-      ;
-
-   FileFd fd;
-   atexit(remove_tmpfile);
-   tempfile = strdup("apt-test.XXXXXXXX");
-   tempfile_fd = mkstemp(tempfile);
-
-   /* (Re-)Open (as FileFd), write and seek to start of the temp file */
-   equals(fd.OpenDescriptor(tempfile_fd, FileFd::ReadWrite), true);
-   equals(fd.Write(contents, strlen(contents)), true);
-   equals(fd.Seek(0), true);
+      "Sections: main non-free\n");
+   fd.Close();
 
-   pkgSourceList sources(tempfile);
-   equals(sources.size(), 2);
+   SourceList sources;
+   EXPECT_EQ(2, sources.ParseFileDeb822(tempfile));
+   EXPECT_EQ(2, sources.size());
 
-   /* clean up handled by atexit handler, so just return here */
-   return 0;
+   unlink(tempfile);
 }

+ 57 - 81
test/libapt/strutil_test.cc

@@ -1,96 +1,72 @@
 #include <config.h>
-
 #include <apt-pkg/strutl.h>
-
 #include <string>
 #include <vector>
 
-#include "assert.h"
+#include <gtest/gtest.h>
 
-int main()
+TEST(StrUtilTest,DeEscapeString)
 {
-   std::string input, output, expected;
-
-   // no input
-   input = "foobar";
-   expected = "foobar";
-   output = DeEscapeString(input);
-   equals(output, expected);
-
+   // nothing special
+   EXPECT_EQ("", DeEscapeString(""));
+   EXPECT_EQ("foobar", DeEscapeString("foobar"));
    // hex and octal
-   input = "foo\\040bar\\x0abaz";
-   expected = "foo bar\nbaz";
-   output = DeEscapeString(input);
-   equals(output, expected);
-
-   // at the end
-   input = "foo\\040";
-   expected = "foo ";
-   output = DeEscapeString(input);
-   equals(output, expected);
-
-   // double escape
-   input = "foo\\\\ x";
-   expected = "foo\\ x";
-   output = DeEscapeString(input);
-   equals(output, expected);
-
-   // double escape at the end
-   input = "\\\\foo\\\\";
-   expected = "\\foo\\";
-   output = DeEscapeString(input);
-   equals(output, expected);
-
-   // the string that we actually need it for
-   input = "/media/Ubuntu\\04011.04\\040amd64";
-   expected = "/media/Ubuntu 11.04 amd64";
-   output = DeEscapeString(input);
-   equals(output, expected);
+   EXPECT_EQ("foo bar\nbaz", DeEscapeString("foo\\040bar\\x0abaz"));
+   EXPECT_EQ("foo ", DeEscapeString("foo\\040"));
+   EXPECT_EQ("\nbaz", DeEscapeString("\\x0abaz"));
+   EXPECT_EQ("/media/Ubuntu 11.04 amd64", DeEscapeString("/media/Ubuntu\\04011.04\\040amd64"));
+   // double slashes
+   EXPECT_EQ("foo\\ x", DeEscapeString("foo\\\\ x"));
+   EXPECT_EQ("\\foo\\", DeEscapeString("\\\\foo\\\\"));
+}
+TEST(StrUtilTest,StringSplitBasic)
+{
+   std::vector<std::string> result = StringSplit("", "");
+   EXPECT_EQ(result.size(), 0);
 
-   // Split
-   input = "status: libnet1:amd64: unpacked";
-   std::vector<std::string> result = StringSplit(input, ": ");
-   equals(result[0], "status");
-   equals(result[1], "libnet1:amd64");
-   equals(result[2], "unpacked");
-   equals(result.size(), 3);
+   result = StringSplit("abc", "");
+   EXPECT_EQ(result.size(), 0);
 
-   input = "status: libnet1:amd64: unpacked";
-   result = StringSplit(input, "xxx");
-   equals(result[0], input);
-   equals(result.size(), 1);
+   result = StringSplit("", "abc");
+   EXPECT_EQ(result.size(), 1);
 
-   input = "status: libnet1:amd64: unpacked";
-   result = StringSplit(input, "");
-   equals(result.size(), 0);
+   result = StringSplit("abc", "b");
+   ASSERT_EQ(result.size(), 2);
+   EXPECT_EQ(result[0], "a");
+   EXPECT_EQ(result[1], "c");
 
-   input = "x:y:z";
-   result = StringSplit(input, ":", 2);
-   equals(result.size(), 2);
-   equals(result[0], "x");
-   equals(result[1], "y:z");
+   result = StringSplit("abc", "abc");
+   ASSERT_EQ(result.size(), 2);
+   EXPECT_EQ(result[0], "");
+   EXPECT_EQ(result[1], "");
+}
+TEST(StrUtilTest,StringSplitDpkgStatus)
+{
+   std::string const input = "status: libnet1:amd64: unpacked";
+   std::vector<std::string> result = StringSplit(input, "xxx");
+   ASSERT_EQ(result.size(), 1);
+   EXPECT_EQ(result[0], input);
 
-   input = "abc";
    result = StringSplit(input, "");
-   equals(result.size(), 0);
-
-   // endswith
-   bool b;
-   input = "abcd";
-   b = APT::String::Endswith(input, "d");
-   equals(b, true);
-
-   b = APT::String::Endswith(input, "cd");
-   equals(b, true);
-
-   b = APT::String::Endswith(input, "abcd");
-   equals(b, true);
-
-   b = APT::String::Endswith(input, "x");
-   equals(b, false);
-
-   b = APT::String::Endswith(input, "abcndefg");
-   equals(b, false);
-
-   return 0;
+   EXPECT_EQ(result.size(), 0);
+
+   result = StringSplit(input, ": ");
+   ASSERT_EQ(result.size(), 3);
+   EXPECT_EQ(result[0], "status");
+   EXPECT_EQ(result[1], "libnet1:amd64");
+   EXPECT_EQ(result[2], "unpacked");
+
+   result = StringSplit("x:y:z", ":", 2);
+   ASSERT_EQ(result.size(), 2);
+   EXPECT_EQ(result[0], "x");
+   EXPECT_EQ(result[1], "y:z");
+}
+TEST(StrUtilTest,EndsWith)
+{
+   using APT::String::Endswith;
+   EXPECT_TRUE(Endswith("abcd", "d"));
+   EXPECT_TRUE(Endswith("abcd", "cd"));
+   EXPECT_TRUE(Endswith("abcd", "abcd"));
+   EXPECT_FALSE(Endswith("abcd", "x"));
+   EXPECT_FALSE(Endswith("abcd", "abcndefg"));
 }

+ 18 - 44
test/libapt/tagfile_test.cc

@@ -8,55 +8,29 @@
 #include <string.h>
 #include <unistd.h>
 
-#include "assert.h"
+#include <gtest/gtest.h>
 
-char *tempfile = NULL;
-int tempfile_fd = -1;
+#include "file-helpers.h"
 
-static void remove_tmpfile(void)
-{
-   if (tempfile_fd > 0)
-      close(tempfile_fd);
-   if (tempfile != NULL) {
-      unlink(tempfile);
-      free(tempfile);
-   }
-}
-
-int main()
+TEST(TagFileTest,SingleField)
 {
    FileFd fd;
-   const char contents[] = "FieldA-12345678: the value of the field";
-   atexit(remove_tmpfile);
-   tempfile = strdup("apt-test.XXXXXXXX");
-   tempfile_fd = mkstemp(tempfile);
-
-   /* (Re-)Open (as FileFd), write and seek to start of the temp file */
-   equals(fd.OpenDescriptor(tempfile_fd, FileFd::ReadWrite), true);
-   equals(fd.Write(contents, strlen(contents)), true);
-   equals(fd.Seek(0), true);
+   createTemporaryFile("singlefield", fd, NULL, "FieldA-12345678: the value of the field");
 
    pkgTagFile tfile(&fd);
    pkgTagSection section;
-   equals(tfile.Step(section), true);
-  
-   /* It has one field */
-   equals(section.Count(), 1);
-
-   /* ... and it is called FieldA-12345678 */
-   equals(section.Exists("FieldA-12345678"), true);
-
-   /* its value is correct */
-   equals(section.FindS("FieldA-12345678"), std::string("the value of the field"));
-   /* A non-existent field has an empty string as value */
-   equals(section.FindS("FieldB-12345678"), std::string());
-
-   /* ... and Exists does not lie about missing fields... */
-   equalsNot(section.Exists("FieldB-12345678"), true); 
-
-   /* There is only one section in this tag file */
-   equals(tfile.Step(section), false);
-
-   /* clean up handled by atexit handler, so just return here */
-   return 0;
+   ASSERT_TRUE(tfile.Step(section));
+
+   // It has one field
+   EXPECT_EQ(1, section.Count());
+   // ... and it is called FieldA-12345678
+   EXPECT_TRUE(section.Exists("FieldA-12345678"));
+   // its value is correct
+   EXPECT_EQ("the value of the field", section.FindS("FieldA-12345678"));
+   // A non-existent field has an empty string as value
+   EXPECT_EQ("", section.FindS("FieldB-12345678"));
+   // ... and Exists does not lie about missing fields...
+   EXPECT_FALSE(section.Exists("FieldB-12345678"));
+   // There is only one section in this tag file
+   EXPECT_FALSE(tfile.Step(section));
 }

+ 114 - 119
test/libapt/uri_test.cc

@@ -1,124 +1,119 @@
 #include <config.h>
-
 #include <apt-pkg/strutl.h>
-
 #include <string>
+#include <gtest/gtest.h>
 
-#include "assert.h"
-
-int main() {
-	// Basic stuff
-	{
-	URI U("http://www.debian.org:90/temp/test");
-	equals("http", U.Access);
-	equals("", U.User);
-	equals("", U.Password);
-	equals(90, U.Port);
-	equals("www.debian.org", U.Host);
-	equals("/temp/test", U.Path);
-	} {
-	URI U("http://jgg:foo@ualberta.ca/blah");
-	equals("http", U.Access);
-	equals("jgg", U.User);
-	equals("foo", U.Password);
-	equals(0, U.Port);
-	equals("ualberta.ca", U.Host);
-	equals("/blah", U.Path);
-	} {
-	URI U("file:/usr/bin/foo");
-	equals("file", U.Access);
-	equals("", U.User);
-	equals("", U.Password);
-	equals(0, U.Port);
-	equals("", U.Host);
-	equals("/usr/bin/foo", U.Path);
-	} {
-	URI U("cdrom:Moo Cow Rom:/debian");
-	equals("cdrom", U.Access);
-	equals("", U.User);
-	equals("", U.Password);
-	equals(0, U.Port);
-	equals("Moo Cow Rom", U.Host);
-	equals("/debian", U.Path);
-	} {
-	URI U("gzip:./bar/cow");
-	equals("gzip", U.Access);
-	equals("", U.User);
-	equals("", U.Password);
-	equals(0, U.Port);
-	equals(".", U.Host);
-	equals("/bar/cow", U.Path);
-	} {
-	URI U("ftp:ftp.fr.debian.org/debian/pool/main/x/xtel/xtel_3.2.1-15_i386.deb");
-	equals("ftp", U.Access);
-	equals("", U.User);
-	equals("", U.Password);
-	equals(0, U.Port);
-	equals("ftp.fr.debian.org", U.Host);
-	equals("/debian/pool/main/x/xtel/xtel_3.2.1-15_i386.deb", U.Path);
-	}
-
-	// RFC 2732 stuff
-	{
-	URI U("http://[1080::8:800:200C:417A]/foo");
-	equals("http", U.Access);
-	equals("", U.User);
-	equals("", U.Password);
-	equals(0, U.Port);
-	equals("1080::8:800:200C:417A", U.Host);
-	equals("/foo", U.Path);
-	} {
-	URI U("http://[::FFFF:129.144.52.38]:80/index.html");
-	equals("http", U.Access);
-	equals("", U.User);
-	equals("", U.Password);
-	equals(80, U.Port);
-	equals("::FFFF:129.144.52.38", U.Host);
-	equals("/index.html", U.Path);
-	} {
-	URI U("http://[::FFFF:129.144.52.38:]:80/index.html");
-	equals("http", U.Access);
-	equals("", U.User);
-	equals("", U.Password);
-	equals(80, U.Port);
-	equals("::FFFF:129.144.52.38:", U.Host);
-	equals("/index.html", U.Path);
-	} {
-	URI U("http://[::FFFF:129.144.52.38:]/index.html");
-	equals("http", U.Access);
-	equals("", U.User);
-	equals("", U.Password);
-	equals(0, U.Port);
-	equals("::FFFF:129.144.52.38:", U.Host);
-	equals("/index.html", U.Path);
-	}
-	/* My Evil Corruption of RFC 2732 to handle CDROM names! Fun for
-	   the whole family! */
-	{
-	URI U("cdrom:[The Debian 1.2 disk, 1/2 R1:6]/debian/");
-	equals("cdrom", U.Access);
-	equals("", U.User);
-	equals("", U.Password);
-	equals(0, U.Port);
-	equals("The Debian 1.2 disk, 1/2 R1:6", U.Host);
-	equals("/debian/", U.Path);
-	} {
-	URI U("cdrom:Foo Bar Cow/debian/");
-	equals("cdrom", U.Access);
-	equals("", U.User);
-	equals("", U.Password);
-	equals(0, U.Port);
-	equals("Foo Bar Cow", U.Host);
-	equals("/debian/", U.Path);
-	}
-
-        // Percent-encoding.
-        {
-        URI U("ftp://foo:b%40r@example.org");
-        equals("foo", U.User);
-        equals("b@r", U.Password);
-        equals("ftp://foo:b%40r@example.org/", (std::string) U);
-        }
-
-	return 0;
+TEST(URITest, BasicHTTP)
+{
+   URI U("http://www.debian.org:90/temp/test");
+   EXPECT_EQ("http", U.Access);
+   EXPECT_EQ("", U.User);
+   EXPECT_EQ("", U.Password);
+   EXPECT_EQ(90, U.Port);
+   EXPECT_EQ("www.debian.org", U.Host);
+   EXPECT_EQ("/temp/test", U.Path);
+   // Login data
+   U = URI("http://jgg:foo@ualberta.ca/blah");
+   EXPECT_EQ("http", U.Access);
+   EXPECT_EQ("jgg", U.User);
+   EXPECT_EQ("foo", U.Password);
+   EXPECT_EQ(0, U.Port);
+   EXPECT_EQ("ualberta.ca", U.Host);
+   EXPECT_EQ("/blah", U.Path);
+}
+TEST(URITest, SingeSlashFile)
+{
+   URI U("file:/usr/bin/foo");
+   EXPECT_EQ("file", U.Access);
+   EXPECT_EQ("", U.User);
+   EXPECT_EQ("", U.Password);
+   EXPECT_EQ(0, U.Port);
+   EXPECT_EQ("", U.Host);
+   EXPECT_EQ("/usr/bin/foo", U.Path);
+}
+TEST(URITest, BasicCDROM)
+{
+   URI U("cdrom:Moo Cow Rom:/debian");
+   EXPECT_EQ("cdrom", U.Access);
+   EXPECT_EQ("", U.User);
+   EXPECT_EQ("", U.Password);
+   EXPECT_EQ(0, U.Port);
+   EXPECT_EQ("Moo Cow Rom", U.Host);
+   EXPECT_EQ("/debian", U.Path);
+}
+TEST(URITest, RelativeGzip)
+{
+   URI U("gzip:./bar/cow");
+   EXPECT_EQ("gzip", U.Access);
+   EXPECT_EQ("", U.User);
+   EXPECT_EQ("", U.Password);
+   EXPECT_EQ(0, U.Port);
+   EXPECT_EQ(".", U.Host);
+   EXPECT_EQ("/bar/cow", U.Path);
+}
+TEST(URITest, NoSlashFTP)
+{
+   URI U("ftp:ftp.fr.debian.org/debian/pool/main/x/xtel/xtel_3.2.1-15_i386.deb");
+   EXPECT_EQ("ftp", U.Access);
+   EXPECT_EQ("", U.User);
+   EXPECT_EQ("", U.Password);
+   EXPECT_EQ(0, U.Port);
+   EXPECT_EQ("ftp.fr.debian.org", U.Host);
+   EXPECT_EQ("/debian/pool/main/x/xtel/xtel_3.2.1-15_i386.deb", U.Path);
+}
+TEST(URITest, RFC2732)
+{
+   URI U("http://[1080::8:800:200C:417A]/foo");
+   EXPECT_EQ("http", U.Access);
+   EXPECT_EQ("", U.User);
+   EXPECT_EQ("", U.Password);
+   EXPECT_EQ(0, U.Port);
+   EXPECT_EQ("1080::8:800:200C:417A", U.Host);
+   EXPECT_EQ("/foo", U.Path);
+   // with port
+   U = URI("http://[::FFFF:129.144.52.38]:80/index.html");
+   EXPECT_EQ("http", U.Access);
+   EXPECT_EQ("", U.User);
+   EXPECT_EQ("", U.Password);
+   EXPECT_EQ(80, U.Port);
+   EXPECT_EQ("::FFFF:129.144.52.38", U.Host);
+   EXPECT_EQ("/index.html", U.Path);
+   // extra colon
+   U = URI("http://[::FFFF:129.144.52.38:]:80/index.html");
+   EXPECT_EQ("http", U.Access);
+   EXPECT_EQ("", U.User);
+   EXPECT_EQ("", U.Password);
+   EXPECT_EQ(80, U.Port);
+   EXPECT_EQ("::FFFF:129.144.52.38:", U.Host);
+   EXPECT_EQ("/index.html", U.Path);
+   // extra colon port
+   U = URI("http://[::FFFF:129.144.52.38:]/index.html");
+   EXPECT_EQ("http", U.Access);
+   EXPECT_EQ("", U.User);
+   EXPECT_EQ("", U.Password);
+   EXPECT_EQ(0, U.Port);
+   EXPECT_EQ("::FFFF:129.144.52.38:", U.Host);
+   EXPECT_EQ("/index.html", U.Path);
+   // My Evil Corruption of RFC 2732 to handle CDROM names!
+   // Fun for the whole family! */
+   U = URI("cdrom:[The Debian 1.2 disk, 1/2 R1:6]/debian/");
+   EXPECT_EQ("cdrom", U.Access);
+   EXPECT_EQ("", U.User);
+   EXPECT_EQ("", U.Password);
+   EXPECT_EQ(0, U.Port);
+   EXPECT_EQ("The Debian 1.2 disk, 1/2 R1:6", U.Host);
+   EXPECT_EQ("/debian/", U.Path);
+   // no brackets
+   U = URI("cdrom:Foo Bar Cow/debian/");
+   EXPECT_EQ("cdrom", U.Access);
+   EXPECT_EQ("", U.User);
+   EXPECT_EQ("", U.Password);
+   EXPECT_EQ(0, U.Port);
+   EXPECT_EQ("Foo Bar Cow", U.Host);
+   EXPECT_EQ("/debian/", U.Path);
+   // percent encoded
+   U = URI("ftp://foo:b%40r@example.org");
+   EXPECT_EQ("foo", U.User);
+   EXPECT_EQ("b@r", U.Password);
+   EXPECT_EQ("ftp://foo:b%40r@example.org/", (std::string) U);
 }

+ 0 - 106
test/libapt/versions.lst

@@ -1,106 +0,0 @@
-# List of 
-#   ver1 ver2 ret 
-# Of versions worth testing
-#  1 means that ver1 > ver2
-# -1 means that ver1 < ver2
-#  0 means that ver1 = ver2
-7.6p2-4 7.6-0 1
-1.0.3-3 1.0-1 1
-1.3 1.2.2-2 1
-1.3 1.2.2 1
-
-# Important attributes
-# disabled as dpkg --compare-versions doesn't like them… (versions have to start with a number)
-#- . -1
-#p - -1
-#a - -1
-#z - -1
-#a . -1
-#z . -1
-
-# disabled as dpkg --compare-versions doesn't like them… (versions have to start with a number)
-#III-alpha9.8 III-alpha9.8-1.5 -1
-
-# Epochs
-1:0.4 10.3 1
-1:1.25-4 1:1.25-8 -1
-0:1.18.36 1.18.36 0
-
-# native version
-1.18.36 1.18.35 1
-0:1.18.36 1.18.35 1
-
-# Funky, but allowed, characters in upstream version
-9:1.18.36:5.4-20 10:0.5.1-22 -1
-9:1.18.36:5.4-20 9:1.18.36:5.5-1 -1
-9:1.18.36:5.4-20 9:1.18.37:4.3-22 -1
-1.18.36-0.17.35-18 1.18.36-19 1
-
-# Junk
-1:1.2.13-3 1:1.2.13-3.1 -1
-2.0.7pre1-4 2.0.7r-1 -1
-
-# Test some properties of text strings
-0-pre 0-pre 0
-0-pre 0-pree -1
-
-1.1.6r2-2 1.1.6r-1 1
-2.6b2-1 2.6b-2 1
-
-98.1p5-1 98.1-pre2-b6-2 -1
-0.4a6-2 0.4-1 1
-
-1:3.0.5-2 1:3.0.5.1 -1
-
-# #205960
-3.0~rc1-1 3.0-1 -1
-
-# #573592 - debian policy 5.6.12
-1.0 1.0-0 0
-0.2 1.0-0 -1
-1.0 1.0-0+b1 -1
-1.0 1.0-0~ 1
-
-# if a version includes a dash
-# it should be the debrev dash - policy says so…
-0:0-0-0 0-0 1
-
-# do we like strange versions? Yes we like strange versions…
-0 0 0
-0 00 0
-
-# "steal" the testcases from cupt
-1.2.3 1.2.3 0 # identical
-4.4.3-2 4.4.3-2 0 # identical
-1:2ab:5 1:2ab:5 0 # this is correct...
-7:1-a:b-5 7:1-a:b-5 0 # and this
-57:1.2.3abYZ+~-4-5 57:1.2.3abYZ+~-4-5 0 # and those too
-1.2.3 0:1.2.3 0 # zero epoch
-1.2.3 1.2.3-0 0 # zero revision
-009 9 0 # zeroes...
-009ab5 9ab5 0 # there as well
-1.2.3 1.2.3-1 -1 # added non-zero revision
-1.2.3 1.2.4 -1 # just bigger
-1.2.4 1.2.3 1 # order doesn't matter
-1.2.24 1.2.3 1 # bigger, eh?
-0.10.0 0.8.7 1 # bigger, eh?
-3.2 2.3 1 # major number rocks
-1.3.2a 1.3.2 1 # letters rock
-0.5.0~git 0.5.0~git2 -1 # numbers rock
-2a 21 -1 # but not in all places
-1.3.2a 1.3.2b -1 # but there is another letter
-1:1.2.3 1.2.4 1 # epoch rocks
-1:1.2.3 1:1.2.4 -1 # bigger anyway
-1.2a+~bCd3 1.2a++ -1 # tilde doesn't rock
-1.2a+~bCd3 1.2a+~ 1 # but first is longer!
-5:2 304-2 1 # epoch rocks
-5:2 304:2 -1 # so big epoch?
-25:2 3:2 1 # 25 > 3, obviously
-1:2:123 1:12:3 -1 # 12 > 2
-1.2-5 1.2-3-5 -1 # 1.2 < 1.2-3
-5.10.0 5.005 1 # preceding zeroes don't matters
-3a9.8 3.10.2 -1 # letters are before all letter symbols
-3a9.8 3~10 1 # but after the tilde
-1.4+OOo3.0.0~ 1.4+OOo3.0.0-4 -1 # another tilde check
-2.4.7-1 2.4.7-z -1 # revision comparing
-1.002-1+b2 1.00 1 # whatever...