From 9f4ce246ab14d7348a0bf268dc9fcef919b534a8 Mon Sep 17 00:00:00 2001 From: Simone Basso Date: Thu, 12 Oct 2023 18:52:17 +0200 Subject: [PATCH 1/4] chore(buildtool): add ios-build unit tests Part of https://github.com/ooni/probe/issues/2564 --- .../internal/buildtooltest/buildtooltest.go | 6 +- internal/cmd/buildtool/ios.go | 2 +- internal/cmd/buildtool/ios_test.go | 921 ++++++++++++++++++ 3 files changed, 925 insertions(+), 4 deletions(-) diff --git a/internal/cmd/buildtool/internal/buildtooltest/buildtooltest.go b/internal/cmd/buildtool/internal/buildtooltest/buildtooltest.go index 4ebcbe7272..46b51018f0 100644 --- a/internal/cmd/buildtool/internal/buildtooltest/buildtooltest.go +++ b/internal/cmd/buildtool/internal/buildtooltest/buildtooltest.go @@ -85,7 +85,7 @@ func CheckSingleCommand(cmd *execabs.Cmd, tee ExecExpectations) error { return err } if err := CompareEnv(tee.Env, shellxtesting.CmdEnvironMinusOsEnviron(cmd)); err != nil { - return err + return fmt.Errorf("in %v: %w", tee.Argv, err) } return nil } @@ -253,12 +253,12 @@ func (*DependenciesCallCounter) XCRun(args ...string) string { case "-sdk": runtimex.Assert(len(args) == 3, "expected three arguments") runtimex.Assert(args[2] == "--show-sdk-path", "the third argument must be --show-sdk-path") - return filepath.Join("Developer", "SDKs", args[1]) + return string(filepath.Separator) + filepath.Join("Developer", "SDKs", args[1]) case "-find": runtimex.Assert(len(args) == 4, "expected four arguments") runtimex.Assert(args[1] == "-sdk", "the second argument must be -sdk") - return filepath.Join("Developer", "SDKs", args[2], "bin", args[3]) + return string(filepath.Separator) + filepath.Join("", "Developer", "SDKs", args[2], "bin", args[3]) default: panic(errors.New("the first argument must be -sdk or -find")) diff --git a/internal/cmd/buildtool/ios.go b/internal/cmd/buildtool/ios.go index 7fa94bc5a9..505bc94e82 100644 --- a/internal/cmd/buildtool/ios.go +++ b/internal/cmd/buildtool/ios.go @@ -150,9 +150,9 @@ func iosNewCBuildEnv(deps buildtoolmodel.Dependencies, ooniArch string) *cBuildE CFLAGS: []string{ "-isysroot", isysroot, minVersionFlag + iosMinVersion, // tricky: they must be concatenated - "-O2", "-arch", appleArch, "-fembed-bitcode", + "-O2", }, CONFIGURE_HOST: "", // later DESTDIR: destdir, diff --git a/internal/cmd/buildtool/ios_test.go b/internal/cmd/buildtool/ios_test.go index 06ff9d3ef9..7f622a0d7b 100644 --- a/internal/cmd/buildtool/ios_test.go +++ b/internal/cmd/buildtool/ios_test.go @@ -1,6 +1,9 @@ package main import ( + "fmt" + "runtime" + "strconv" "testing" "github.com/google/go-cmp/cmp" @@ -119,3 +122,921 @@ func TestIOSBuildGomobile(t *testing.T) { }) } } + +func TestIOSBuildCdepsZlib(t *testing.T) { + faketopdir := (&buildtooltest.DependenciesCallCounter{}).AbsoluteCurDir() + + // testspec specifies a test case for this test + type testspec struct { + // name is the name of the test case + name string + + // expectations contains the commands we expect to see + expect []buildtooltest.ExecExpectations + } + + var testcases = []testspec{{ + name: "zlib", + expect: []buildtooltest.ExecExpectations{{ + Env: []string{}, + Argv: []string{ + "curl", "-fsSLO", "https://zlib.net/zlib-1.3.tar.gz", + }, + }, { + Env: []string{}, + Argv: []string{ + "tar", "-xf", "zlib-1.3.tar.gz", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/zlib/000.patch", + }, + }, { + Env: []string{ + "AR=/Developer/SDKs/iphoneos/bin/ar", + "AS=/Developer/SDKs/iphoneos/bin/as", + "CC=/Developer/SDKs/iphoneos/bin/cc", + "CFLAGS=-isysroot /Developer/SDKs/iphoneos -miphoneos-version-min=12.0 -arch arm64 -fembed-bitcode -O2", + "CXX=/Developer/SDKs/iphoneos/bin/c++", + "CXXFLAGS=-isysroot /Developer/SDKs/iphoneos -miphoneos-version-min=12.0 -arch arm64 -fembed-bitcode -O2", + "LD=/Developer/SDKs/iphoneos/bin/ld", + "LDFLAGS=-isysroot /Developer/SDKs/iphoneos -miphoneos-version-min=12.0 -arch arm64 -fembed-bitcode", + "RANLIB=/Developer/SDKs/iphoneos/bin/ranlib", + "STRIP=/Developer/SDKs/iphoneos/bin/strip", + "CHOST=arm-apple-darwin", + }, + Argv: []string{ + "./configure", "--prefix=/", "--static", + }, + }, { + Env: []string{}, + Argv: []string{ + "make", "-j", strconv.Itoa(runtime.NumCPU()), + }, + }, { + Env: []string{}, + Argv: []string{ + "make", + "DESTDIR=" + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64", + "install", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", "-rf", faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/lib/pkgconfig", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", "-rf", faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/share", + }, + }, { + Env: []string{}, + Argv: []string{ + "curl", "-fsSLO", "https://zlib.net/zlib-1.3.tar.gz", + }, + }, { + Env: []string{}, + Argv: []string{ + "tar", "-xf", "zlib-1.3.tar.gz", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/zlib/000.patch", + }, + }, { + Env: []string{ + "AR=/Developer/SDKs/iphonesimulator/bin/ar", + "AS=/Developer/SDKs/iphonesimulator/bin/as", + "CC=/Developer/SDKs/iphonesimulator/bin/cc", + "CFLAGS=-isysroot /Developer/SDKs/iphonesimulator -miphonesimulator-version-min=12.0 -arch x86_64 -fembed-bitcode -O2", + "CXX=/Developer/SDKs/iphonesimulator/bin/c++", + "CXXFLAGS=-isysroot /Developer/SDKs/iphonesimulator -miphonesimulator-version-min=12.0 -arch x86_64 -fembed-bitcode -O2", + "LD=/Developer/SDKs/iphonesimulator/bin/ld", + "LDFLAGS=-isysroot /Developer/SDKs/iphonesimulator -miphonesimulator-version-min=12.0 -arch x86_64 -fembed-bitcode", + "RANLIB=/Developer/SDKs/iphonesimulator/bin/ranlib", + "STRIP=/Developer/SDKs/iphonesimulator/bin/strip", + "CHOST=x86_64-apple-darwin", + }, + Argv: []string{ + "./configure", "--prefix=/", "--static", + }, + }, { + Env: []string{}, + Argv: []string{ + "make", "-j", strconv.Itoa(runtime.NumCPU()), + }, + }, { + Env: []string{}, + Argv: []string{ + "make", + "DESTDIR=" + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64", + "install", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", "-rf", faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/lib/pkgconfig", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", "-rf", faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/share", + }, + }}, + }} + + for _, testcase := range testcases { + t.Run(testcase.name, func(t *testing.T) { + + cc := &buildtooltest.SimpleCommandCollector{} + + deps := &buildtooltest.DependenciesCallCounter{ + HasPsiphon: false, + } + + shellxtesting.WithCustomLibrary(cc, func() { + iosCdepsBuildMain("zlib", deps) + }) + + expectCalls := map[string]int{ + buildtooltest.TagAbsoluteCurDir: 2, + buildtooltest.TagMustChdir: 2, + buildtooltest.TagVerifySHA256: 2, + } + + if diff := cmp.Diff(expectCalls, deps.Counter); diff != "" { + t.Fatal(diff) + } + + if err := buildtooltest.CheckManyCommands(cc.Commands, testcase.expect); err != nil { + t.Fatal(err) + } + }) + } +} + +func TestIOSBuildCdepsOpenSSL(t *testing.T) { + faketopdir := (&buildtooltest.DependenciesCallCounter{}).AbsoluteCurDir() + + // testspec specifies a test case for this test + type testspec struct { + // name is the name of the test case + name string + + // expectations contains the commands we expect to see + expect []buildtooltest.ExecExpectations + } + + var testcases = []testspec{{ + name: "openssl", + expect: []buildtooltest.ExecExpectations{{ + Env: []string{}, + Argv: []string{ + "curl", "-fsSLO", "https://www.openssl.org/source/openssl-3.1.3.tar.gz", + }, + }, { + Env: []string{}, + Argv: []string{ + "tar", "-xf", "openssl-3.1.3.tar.gz", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/openssl/000.patch", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/openssl/001.patch", + }, + }, { + Env: []string{ + "CFLAGS=-isysroot /Developer/SDKs/iphoneos -miphoneos-version-min=12.0 -arch arm64 -fembed-bitcode -O2 -Wno-macro-redefined", + "LDFLAGS=-isysroot /Developer/SDKs/iphoneos -miphoneos-version-min=12.0 -arch arm64 -fembed-bitcode", + "CXXFLAGS=-isysroot /Developer/SDKs/iphoneos -miphoneos-version-min=12.0 -arch arm64 -fembed-bitcode -O2 -Wno-macro-redefined", + }, + Argv: []string{ + "./Configure", "no-comp", "no-dtls", "no-ec2m", "no-psk", "no-srp", + "no-ssl3", "no-camellia", "no-idea", "no-md2", "no-md4", "no-mdc2", + "no-rc2", "no-rc4", "no-rc5", "no-rmd160", "no-whirlpool", "no-dso", + "no-ui-console", "no-shared", "no-unit-test", "ios64-xcrun", + "-miphoneos-version-min=12.0", "-fembed-bitcode", + "--libdir=lib", "--prefix=/", "--openssldir=/", + }, + }, { + Env: []string{ + "CFLAGS=-isysroot /Developer/SDKs/iphoneos -miphoneos-version-min=12.0 -arch arm64 -fembed-bitcode -O2 -Wno-macro-redefined", + "LDFLAGS=-isysroot /Developer/SDKs/iphoneos -miphoneos-version-min=12.0 -arch arm64 -fembed-bitcode", + "CXXFLAGS=-isysroot /Developer/SDKs/iphoneos -miphoneos-version-min=12.0 -arch arm64 -fembed-bitcode -O2 -Wno-macro-redefined", + }, + Argv: []string{ + "make", "-j", strconv.Itoa(runtime.NumCPU()), + }, + }, { + Env: []string{}, + Argv: []string{ + "make", + "DESTDIR=" + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64", + "install_dev", + }, + }, { + Env: []string{}, + Argv: []string{ + "curl", "-fsSLO", "https://www.openssl.org/source/openssl-3.1.3.tar.gz", + }, + }, { + Env: []string{}, + Argv: []string{ + "tar", "-xf", "openssl-3.1.3.tar.gz", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/openssl/000.patch", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/openssl/001.patch", + }, + }, { + Env: []string{ + "CFLAGS=-isysroot /Developer/SDKs/iphonesimulator -miphonesimulator-version-min=12.0 -arch x86_64 -fembed-bitcode -O2 -Wno-macro-redefined", + "LDFLAGS=-isysroot /Developer/SDKs/iphonesimulator -miphonesimulator-version-min=12.0 -arch x86_64 -fembed-bitcode", + "CXXFLAGS=-isysroot /Developer/SDKs/iphonesimulator -miphonesimulator-version-min=12.0 -arch x86_64 -fembed-bitcode -O2 -Wno-macro-redefined", + }, + Argv: []string{ + "./Configure", "no-comp", "no-dtls", "no-ec2m", "no-psk", "no-srp", + "no-ssl3", "no-camellia", "no-idea", "no-md2", "no-md4", "no-mdc2", + "no-rc2", "no-rc4", "no-rc5", "no-rmd160", "no-whirlpool", "no-dso", + "no-ui-console", "no-shared", "no-unit-test", "iossimulator-xcrun", + "-miphonesimulator-version-min=12.0", "-fembed-bitcode", + "--libdir=lib", "--prefix=/", "--openssldir=/", + }, + }, { + Env: []string{ + "CFLAGS=-isysroot /Developer/SDKs/iphonesimulator -miphonesimulator-version-min=12.0 -arch x86_64 -fembed-bitcode -O2 -Wno-macro-redefined", + "LDFLAGS=-isysroot /Developer/SDKs/iphonesimulator -miphonesimulator-version-min=12.0 -arch x86_64 -fembed-bitcode", + "CXXFLAGS=-isysroot /Developer/SDKs/iphonesimulator -miphonesimulator-version-min=12.0 -arch x86_64 -fembed-bitcode -O2 -Wno-macro-redefined", + }, + Argv: []string{ + "make", "-j", strconv.Itoa(runtime.NumCPU()), + }, + }, { + Env: []string{}, + Argv: []string{ + "make", + "DESTDIR=" + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64", + "install_dev", + }, + }}, + }} + + for _, testcase := range testcases { + t.Run(testcase.name, func(t *testing.T) { + + cc := &buildtooltest.SimpleCommandCollector{} + + deps := &buildtooltest.DependenciesCallCounter{ + HasPsiphon: false, + } + + shellxtesting.WithCustomLibrary(cc, func() { + iosCdepsBuildMain("openssl", deps) + }) + + expectCalls := map[string]int{ + buildtooltest.TagAbsoluteCurDir: 2, + buildtooltest.TagMustChdir: 2, + buildtooltest.TagVerifySHA256: 2, + } + + if diff := cmp.Diff(expectCalls, deps.Counter); diff != "" { + t.Fatal(diff) + } + + if err := buildtooltest.CheckManyCommands(cc.Commands, testcase.expect); err != nil { + t.Fatal(err) + } + }) + } +} + +func TestIOSBuildCdepsLibevent(t *testing.T) { + faketopdir := (&buildtooltest.DependenciesCallCounter{}).AbsoluteCurDir() + + // testspec specifies a test case for this test + type testspec struct { + // name is the name of the test case + name string + + // expectations contains the commands we expect to see + expect []buildtooltest.ExecExpectations + } + + var testcases = []testspec{{ + name: "libevent", + expect: []buildtooltest.ExecExpectations{{ + Env: []string{}, + Argv: []string{ + "curl", + "-fsSLO", + "https://github.com/libevent/libevent/archive/release-2.1.12-stable.tar.gz", + }, + }, { + Env: []string{}, + Argv: []string{ + "tar", "-xf", "release-2.1.12-stable.tar.gz", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/libevent/000.patch", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/libevent/001.patch", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/libevent/002.patch", + }, + }, { + Env: []string{}, + Argv: []string{ + "./autogen.sh", + }, + }, { + Env: []string{ + "AS=/Developer/SDKs/iphoneos/bin/as", + "LD=/Developer/SDKs/iphoneos/bin/ld", + "CXX=/Developer/SDKs/iphoneos/bin/c++", + "CC=/Developer/SDKs/iphoneos/bin/cc", + "AR=/Developer/SDKs/iphoneos/bin/ar", + "RANLIB=/Developer/SDKs/iphoneos/bin/ranlib", + "STRIP=/Developer/SDKs/iphoneos/bin/strip", + fmt.Sprintf( + "%s %s", + "LDFLAGS=-isysroot /Developer/SDKs/iphoneos -miphoneos-version-min=12.0 -arch arm64 -fembed-bitcode", + "-L"+faketopdir+"/internal/cmd/buildtool/internal/libtor/ios/arm64/lib", + ), + fmt.Sprintf( + "%s %s", + "CFLAGS=-isysroot /Developer/SDKs/iphoneos -miphoneos-version-min=12.0 -arch arm64 -fembed-bitcode -O2", + "-I"+faketopdir+"/internal/cmd/buildtool/internal/libtor/ios/arm64/include", + ), + fmt.Sprintf( + "%s %s", + "CXXFLAGS=-isysroot /Developer/SDKs/iphoneos -miphoneos-version-min=12.0 -arch arm64 -fembed-bitcode -O2", + "-I"+faketopdir+"/internal/cmd/buildtool/internal/libtor/ios/arm64/include", + ), + "PKG_CONFIG_PATH=" + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/lib/pkgconfig", + }, + Argv: []string{ + "./configure", + "--host=arm-apple-darwin", + "--disable-libevent-regress", + "--disable-samples", + "--disable-shared", + "--prefix=/", + }, + }, { + Env: []string{}, + Argv: []string{ + "make", "V=1", "-j", strconv.Itoa(runtime.NumCPU()), + }, + }, { + Env: []string{}, + Argv: []string{ + "make", + "DESTDIR=" + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64", + "install", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/bin", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-f", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/lib/pkgconfig/libevent.pc", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-f", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/lib/pkgconfig/libevent_core.pc", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-f", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/lib/pkgconfig/libevent_extra.pc", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-f", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/lib/pkgconfig/libevent_openssl.pc", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-f", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/lib/pkgconfig/libevent_pthreads.pc", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/lib/libevent.la", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/lib/libevent_core.a", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/lib/libevent_core.la", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/lib/libevent_extra.a", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/lib/libevent_extra.la", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/lib/libevent_openssl.a", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/lib/libevent_openssl.la", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/lib/libevent_pthreads.a", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/lib/libevent_pthreads.la", + }, + }, { + Env: []string{}, + Argv: []string{ + "curl", + "-fsSLO", + "https://github.com/libevent/libevent/archive/release-2.1.12-stable.tar.gz", + }, + }, { + Env: []string{}, + Argv: []string{ + "tar", "-xf", "release-2.1.12-stable.tar.gz", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/libevent/000.patch", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/libevent/001.patch", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/libevent/002.patch", + }, + }, { + Env: []string{}, + Argv: []string{ + "./autogen.sh", + }, + }, { + Env: []string{ + "AS=/Developer/SDKs/iphonesimulator/bin/as", + "LD=/Developer/SDKs/iphonesimulator/bin/ld", + "CXX=/Developer/SDKs/iphonesimulator/bin/c++", + "CC=/Developer/SDKs/iphonesimulator/bin/cc", + "AR=/Developer/SDKs/iphonesimulator/bin/ar", + "RANLIB=/Developer/SDKs/iphonesimulator/bin/ranlib", + "STRIP=/Developer/SDKs/iphonesimulator/bin/strip", + fmt.Sprintf( + "%s %s", + "LDFLAGS=-isysroot /Developer/SDKs/iphonesimulator -miphonesimulator-version-min=12.0 -arch x86_64 -fembed-bitcode", + "-L"+faketopdir+"/internal/cmd/buildtool/internal/libtor/ios/amd64/lib", + ), + fmt.Sprintf( + "%s %s", + "CFLAGS=-isysroot /Developer/SDKs/iphonesimulator -miphonesimulator-version-min=12.0 -arch x86_64 -fembed-bitcode -O2", + "-I"+faketopdir+"/internal/cmd/buildtool/internal/libtor/ios/amd64/include", + ), + fmt.Sprintf( + "%s %s", + "CXXFLAGS=-isysroot /Developer/SDKs/iphonesimulator -miphonesimulator-version-min=12.0 -arch x86_64 -fembed-bitcode -O2", + "-I"+faketopdir+"/internal/cmd/buildtool/internal/libtor/ios/amd64/include", + ), + "PKG_CONFIG_PATH=" + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/lib/pkgconfig", + }, + Argv: []string{ + "./configure", + "--host=x86_64-apple-darwin", + "--disable-libevent-regress", + "--disable-samples", + "--disable-shared", + "--prefix=/", + }, + }, { + Env: []string{}, + Argv: []string{ + "make", "V=1", "-j", strconv.Itoa(runtime.NumCPU()), + }, + }, { + Env: []string{}, + Argv: []string{ + "make", + "DESTDIR=" + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64", + "install", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/bin", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-f", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/lib/pkgconfig/libevent.pc", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-f", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/lib/pkgconfig/libevent_core.pc", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-f", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/lib/pkgconfig/libevent_extra.pc", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-f", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/lib/pkgconfig/libevent_openssl.pc", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-f", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/lib/pkgconfig/libevent_pthreads.pc", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/lib/libevent.la", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/lib/libevent_core.a", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/lib/libevent_core.la", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/lib/libevent_extra.a", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/lib/libevent_extra.la", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/lib/libevent_openssl.a", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/lib/libevent_openssl.la", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/lib/libevent_pthreads.a", + }, + }, { + Env: []string{}, + Argv: []string{ + "rm", + "-rf", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/lib/libevent_pthreads.la", + }, + }}, + }} + + for _, testcase := range testcases { + t.Run(testcase.name, func(t *testing.T) { + + cc := &buildtooltest.SimpleCommandCollector{} + + deps := &buildtooltest.DependenciesCallCounter{ + HasPsiphon: false, + } + + shellxtesting.WithCustomLibrary(cc, func() { + iosCdepsBuildMain("libevent", deps) + }) + + expectCalls := map[string]int{ + buildtooltest.TagAbsoluteCurDir: 2, + buildtooltest.TagMustChdir: 2, + buildtooltest.TagVerifySHA256: 2, + } + + if diff := cmp.Diff(expectCalls, deps.Counter); diff != "" { + t.Fatal(diff) + } + + if err := buildtooltest.CheckManyCommands(cc.Commands, testcase.expect); err != nil { + t.Fatal(err) + } + }) + } +} + +func TestIOSBuildCdepsTor(t *testing.T) { + faketopdir := (&buildtooltest.DependenciesCallCounter{}).AbsoluteCurDir() + + // testspec specifies a test case for this test + type testspec struct { + // name is the name of the test case + name string + + // expectations contains the commands we expect to see + expect []buildtooltest.ExecExpectations + } + + var testcases = []testspec{{ + name: "tor", + expect: []buildtooltest.ExecExpectations{{ + Env: []string{}, + Argv: []string{ + "curl", "-fsSLO", "https://www.torproject.org/dist/tor-0.4.8.7.tar.gz", + }, + }, { + Env: []string{}, + Argv: []string{ + "tar", "-xf", "tor-0.4.8.7.tar.gz", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/tor/000.patch", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/tor/001.patch", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/tor/002.patch", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/tor/003.patch", + }, + }, { + Env: []string{ + "AS=/Developer/SDKs/iphoneos/bin/as", + "CC=/Developer/SDKs/iphoneos/bin/cc", + "RANLIB=/Developer/SDKs/iphoneos/bin/ranlib", + "STRIP=/Developer/SDKs/iphoneos/bin/strip", + "CXXFLAGS=-isysroot /Developer/SDKs/iphoneos -miphoneos-version-min=12.0 -arch arm64 -fembed-bitcode -O2", + "CFLAGS=-isysroot /Developer/SDKs/iphoneos -miphoneos-version-min=12.0 -arch arm64 -fembed-bitcode -O2", + "LDFLAGS=-isysroot /Developer/SDKs/iphoneos -miphoneos-version-min=12.0 -arch arm64 -fembed-bitcode", + "CXX=/Developer/SDKs/iphoneos/bin/c++", + "LD=/Developer/SDKs/iphoneos/bin/ld", + "AR=/Developer/SDKs/iphoneos/bin/ar", + }, + Argv: []string{ + "./configure", + "--host=arm-apple-darwin", + "--enable-pic", + "--enable-static-libevent", + "--with-libevent-dir=" + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64", + "--enable-static-openssl", + "--with-openssl-dir=" + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64", + "--enable-static-zlib", + "--with-zlib-dir=" + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64", + "--disable-module-dirauth", + "--disable-zstd", + "--disable-lzma", + "--disable-tool-name-check", + "--disable-systemd", + "--prefix=/", + "--disable-unittests", + }, + }, { + Env: []string{}, + Argv: []string{ + "make", "V=1", "-j", strconv.Itoa(runtime.NumCPU()), + }, + }, { + Env: []string{}, + Argv: []string{ + "install", "-m644", "src/feature/api/tor_api.h", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/include", + }, + }, { + Env: []string{}, + Argv: []string{ + "install", "-m644", "libtor.a", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/arm64/lib", + }, + }, { + Env: []string{}, + Argv: []string{ + "curl", "-fsSLO", "https://www.torproject.org/dist/tor-0.4.8.7.tar.gz", + }, + }, { + Env: []string{}, + Argv: []string{ + "tar", "-xf", "tor-0.4.8.7.tar.gz", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/tor/000.patch", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/tor/001.patch", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/tor/002.patch", + }, + }, { + Env: []string{}, + Argv: []string{ + "git", "apply", faketopdir + "/CDEPS/tor/003.patch", + }, + }, { + Env: []string{ + "AS=/Developer/SDKs/iphonesimulator/bin/as", + "CC=/Developer/SDKs/iphonesimulator/bin/cc", + "RANLIB=/Developer/SDKs/iphonesimulator/bin/ranlib", + "STRIP=/Developer/SDKs/iphonesimulator/bin/strip", + "CXXFLAGS=-isysroot /Developer/SDKs/iphonesimulator -miphonesimulator-version-min=12.0 -arch x86_64 -fembed-bitcode -O2", + "CFLAGS=-isysroot /Developer/SDKs/iphonesimulator -miphonesimulator-version-min=12.0 -arch x86_64 -fembed-bitcode -O2", + "LDFLAGS=-isysroot /Developer/SDKs/iphonesimulator -miphonesimulator-version-min=12.0 -arch x86_64 -fembed-bitcode", + "CXX=/Developer/SDKs/iphonesimulator/bin/c++", + "LD=/Developer/SDKs/iphonesimulator/bin/ld", + "AR=/Developer/SDKs/iphonesimulator/bin/ar", + }, + Argv: []string{ + "./configure", + "--host=x86_64-apple-darwin", + "--enable-pic", + "--enable-static-libevent", + "--with-libevent-dir=" + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64", + "--enable-static-openssl", + "--with-openssl-dir=" + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64", + "--enable-static-zlib", + "--with-zlib-dir=" + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64", + "--disable-module-dirauth", + "--disable-zstd", + "--disable-lzma", + "--disable-tool-name-check", + "--disable-systemd", + "--prefix=/", + "--disable-unittests", + }, + }, { + Env: []string{}, + Argv: []string{ + "make", "V=1", "-j", strconv.Itoa(runtime.NumCPU()), + }, + }, { + Env: []string{}, + Argv: []string{ + "install", "-m644", "src/feature/api/tor_api.h", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/include", + }, + }, { + Env: []string{}, + Argv: []string{ + "install", "-m644", "libtor.a", + faketopdir + "/internal/cmd/buildtool/internal/libtor/ios/amd64/lib", + }, + }}, + }} + + for _, testcase := range testcases { + t.Run(testcase.name, func(t *testing.T) { + + cc := &buildtooltest.SimpleCommandCollector{} + + deps := &buildtooltest.DependenciesCallCounter{ + HasPsiphon: false, + } + + shellxtesting.WithCustomLibrary(cc, func() { + iosCdepsBuildMain("tor", deps) + }) + + expectCalls := map[string]int{ + buildtooltest.TagAbsoluteCurDir: 2, + buildtooltest.TagMustChdir: 2, + buildtooltest.TagVerifySHA256: 2, + } + + if diff := cmp.Diff(expectCalls, deps.Counter); diff != "" { + t.Fatal(diff) + } + + if err := buildtooltest.CheckManyCommands(cc.Commands, testcase.expect); err != nil { + t.Fatal(err) + } + }) + } +} From 8d065e91e677423afde9f946ed50c49658807c9d Mon Sep 17 00:00:00 2001 From: Simone Basso Date: Thu, 12 Oct 2023 18:53:49 +0200 Subject: [PATCH 2/4] Update internal/cmd/buildtool/internal/buildtooltest/buildtooltest.go --- internal/cmd/buildtool/internal/buildtooltest/buildtooltest.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cmd/buildtool/internal/buildtooltest/buildtooltest.go b/internal/cmd/buildtool/internal/buildtooltest/buildtooltest.go index 46b51018f0..e9081489f4 100644 --- a/internal/cmd/buildtool/internal/buildtooltest/buildtooltest.go +++ b/internal/cmd/buildtool/internal/buildtooltest/buildtooltest.go @@ -258,7 +258,7 @@ func (*DependenciesCallCounter) XCRun(args ...string) string { case "-find": runtimex.Assert(len(args) == 4, "expected four arguments") runtimex.Assert(args[1] == "-sdk", "the second argument must be -sdk") - return string(filepath.Separator) + filepath.Join("", "Developer", "SDKs", args[2], "bin", args[3]) + return string(filepath.Separator) + filepath.Join("Developer", "SDKs", args[2], "bin", args[3]) default: panic(errors.New("the first argument must be -sdk or -find")) From f5ff101648b34eddf06e827399bbb9179caaf276 Mon Sep 17 00:00:00 2001 From: Simone Basso Date: Thu, 12 Oct 2023 19:01:11 +0200 Subject: [PATCH 3/4] x --- internal/cmd/buildtool/ios.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/cmd/buildtool/ios.go b/internal/cmd/buildtool/ios.go index 505bc94e82..d1c9824407 100644 --- a/internal/cmd/buildtool/ios.go +++ b/internal/cmd/buildtool/ios.go @@ -37,6 +37,7 @@ func iosSubcommand() *cobra.Command { Use: "cdeps [zlib|openssl|libevent|tor...]", Short: "Cross compiles C dependencies for iOS", Run: func(cmd *cobra.Command, args []string) { + runtimex.Assert(runtime.GOOS == "darwin", "this command requires darwin") for _, arg := range args { iosCdepsBuildMain(arg, &buildDeps{}) } @@ -66,8 +67,6 @@ func iosBuildGomobile(deps buildtoolmodel.Dependencies) { // iosCdepsBuildMain builds C dependencies for ios. func iosCdepsBuildMain(name string, deps buildtoolmodel.Dependencies) { - runtimex.Assert(runtime.GOOS == "darwin", "this command requires darwin") - // The ooni/probe-ios app explicitly only targets amd64 and arm64. It also targets // as the minimum version iOS 12, while one cannot target a version of iOS > 10 when // building for 32-bit targets. Hence, using only 64 bit archs here is fine. From 9b909a45bd4d02bcb94309249ff250b5b36d4735 Mon Sep 17 00:00:00 2001 From: Simone Basso Date: Thu, 12 Oct 2023 19:04:32 +0200 Subject: [PATCH 4/4] x --- internal/cmd/buildtool/android.go | 32 +++++++++++++++++-------------- internal/cmd/buildtool/ios.go | 2 ++ 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/internal/cmd/buildtool/android.go b/internal/cmd/buildtool/android.go index b8a4d88d39..174aa6d7a4 100644 --- a/internal/cmd/buildtool/android.go +++ b/internal/cmd/buildtool/android.go @@ -31,6 +31,12 @@ func androidSubcommand() *cobra.Command { Use: "gomobile", Short: "Builds oonimkall for android using gomobile", Run: func(cmd *cobra.Command, args []string) { + // Implementation note: perform the check here such that we can + // run unit test for the building code from any system + runtimex.Assert( + runtime.GOOS == "darwin" || runtime.GOOS == "linux", + "this command requires darwin or linux", + ) androidBuildGomobile(&buildDeps{}) }, }) @@ -39,6 +45,12 @@ func androidSubcommand() *cobra.Command { Use: "cli", Short: "Builds ooniprobe and miniooni for usage within termux", Run: func(cmd *cobra.Command, args []string) { + // Implementation note: perform the check here such that we can + // run unit test for the building code from any system + runtimex.Assert( + runtime.GOOS == "darwin" || runtime.GOOS == "linux", + "this command requires darwin or linux", + ) androidBuildCLIAll(&buildDeps{}) }, }) @@ -48,6 +60,12 @@ func androidSubcommand() *cobra.Command { Short: "Cross compiles C dependencies for Android", Run: func(cmd *cobra.Command, args []string) { for _, arg := range args { + // Implementation note: perform the check here such that we can + // run unit test for the building code from any system + runtimex.Assert( + runtime.GOOS == "darwin" || runtime.GOOS == "linux", + "this command requires darwin or linux", + ) androidCdepsBuildMain(arg, &buildDeps{}) } }, @@ -59,11 +77,6 @@ func androidSubcommand() *cobra.Command { // androidBuildGomobile invokes the gomobile build. func androidBuildGomobile(deps buildtoolmodel.Dependencies) { - runtimex.Assert( - runtime.GOOS == "darwin" || runtime.GOOS == "linux", - "this command requires darwin or linux", - ) - deps.PsiphonMaybeCopyConfigFiles() deps.GolangCheck() @@ -132,11 +145,6 @@ func androidNDKCheck(androidHome string) string { // androidBuildCLIAll builds all products in CLI mode for Android func androidBuildCLIAll(deps buildtoolmodel.Dependencies) { - runtimex.Assert( - runtime.GOOS == "darwin" || runtime.GOOS == "linux", - "this command requires darwin or linux", - ) - deps.PsiphonMaybeCopyConfigFiles() deps.GolangCheck() @@ -379,10 +387,6 @@ func androidNDKBinPath(ndkDir string) string { // androidCdepsBuildMain builds C dependencies for android. func androidCdepsBuildMain(name string, deps buildtoolmodel.Dependencies) { - runtimex.Assert( - runtime.GOOS == "darwin" || runtime.GOOS == "linux", - "this command requires darwin or linux", - ) androidHome := deps.AndroidSDKCheck() ndkDir := deps.AndroidNDKCheck(androidHome) archs := []string{"arm", "arm64", "386", "amd64"} diff --git a/internal/cmd/buildtool/ios.go b/internal/cmd/buildtool/ios.go index d1c9824407..44af8b54a2 100644 --- a/internal/cmd/buildtool/ios.go +++ b/internal/cmd/buildtool/ios.go @@ -37,6 +37,8 @@ func iosSubcommand() *cobra.Command { Use: "cdeps [zlib|openssl|libevent|tor...]", Short: "Cross compiles C dependencies for iOS", Run: func(cmd *cobra.Command, args []string) { + // Implementation note: perform the check here such that we can + // run unit test for the building code from any system runtimex.Assert(runtime.GOOS == "darwin", "this command requires darwin") for _, arg := range args { iosCdepsBuildMain(arg, &buildDeps{})