blob: a5852a3c4f4dd6d7860d65dec8369a7f5d17b034 [file] [log] [blame]
// Copyright 2016 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/main/cpp/blaze_util.h"
#include "src/main/cpp/util/file.h"
#include "src/main/cpp/util/port.h"
#include "src/main/cpp/util/strings.h"
#include "src/tools/singlejar/input_jar.h"
#include "src/tools/singlejar/options.h"
#include "src/tools/singlejar/output_jar.h"
#include "src/tools/singlejar/test_util.h"
#include "gtest/gtest.h"
namespace {
#if !defined(DATA_DIR_TOP)
#define DATA_DIR_TOP
#endif
static bool HasSubstr(const std::string &s, const std::string &what) {
return std::string::npos != s.find(what);
}
class OutputJarSimpleTest : public ::testing::Test {
protected:
void CreateOutput(const std::string &out_path, const char *first_arg...) {
std::string args_string;
va_list ap;
va_start(ap, first_arg);
const char *args[100] = {"--output", out_path.c_str()};
unsigned nargs = 2;
if (first_arg) {
args[nargs++] = first_arg;
while (nargs < arraysize(args)) {
const char *arg = va_arg(ap, const char *);
if (arg) {
args[nargs++] = arg;
args_string += ' ';
args_string += arg;
} else {
break;
}
}
va_end(ap);
ASSERT_GE(arraysize(args), nargs);
}
printf("Arguments: %s\n", args_string.c_str());
options_.ParseCommandLine(nargs, args);
ASSERT_EQ(0, output_jar_.Doit(&options_));
EXPECT_EQ(0, singlejar_test_util::VerifyZip(out_path));
}
OutputJar output_jar_;
Options options_;
};
// No inputs at all.
TEST_F(OutputJarSimpleTest, Empty) {
std::string out_path = singlejar_test_util::OutputFilePath("out.jar");
CreateOutput(out_path, nullptr);
InputJar input_jar;
ASSERT_TRUE(input_jar.Open(out_path));
const LH *lh;
const CDH *cdh;
while ((cdh = input_jar.NextEntry(&lh))) {
ASSERT_TRUE(cdh->is()) << "No expected tag in the Central Directory Entry.";
ASSERT_NE(nullptr, lh) << "No local header.";
ASSERT_TRUE(lh->is()) << "No expected tag in the Local Header.";
EXPECT_EQ(lh->file_name_string(), cdh->file_name_string());
if (!cdh->no_size_in_local_header()) {
EXPECT_EQ(lh->compressed_file_size(), cdh->compressed_file_size())
<< "Entry: " << lh->file_name_string();
EXPECT_EQ(lh->uncompressed_file_size(), cdh->uncompressed_file_size())
<< "Entry: " << cdh->file_name_string();
}
}
input_jar.Close();
std::string manifest =
singlejar_test_util::GetEntryContents(out_path, "META-INF/MANIFEST.MF");
EXPECT_EQ(
"Manifest-Version: 1.0\r\n"
"Created-By: singlejar\r\n"
"\r\n",
manifest);
std::string build_properties =
singlejar_test_util::GetEntryContents(out_path, "build-data.properties");
EXPECT_PRED2(HasSubstr, build_properties, "build.target=");
}
// Source jars.
TEST_F(OutputJarSimpleTest, Source) {
std::string out_path = singlejar_test_util::OutputFilePath("out.jar");
CreateOutput(out_path, "--sources",
DATA_DIR_TOP "src/tools/singlejar/libtest1.jar",
DATA_DIR_TOP "src/tools/singlejar/libtest2.jar", nullptr);
InputJar input_jar;
ASSERT_TRUE(input_jar.Open(out_path));
const LH *lh;
const CDH *cdh;
while ((cdh = input_jar.NextEntry(&lh))) {
ASSERT_TRUE(cdh->is()) << "No expected tag in the Central Directory Entry.";
ASSERT_NE(nullptr, lh) << "No local header.";
ASSERT_TRUE(lh->is()) << "No expected tag in the Local Header.";
EXPECT_EQ(lh->file_name_string(), cdh->file_name_string());
if (!cdh->no_size_in_local_header()) {
EXPECT_EQ(lh->compressed_file_size(), cdh->compressed_file_size())
<< "Entry: " << lh->file_name_string();
EXPECT_EQ(lh->uncompressed_file_size(), cdh->uncompressed_file_size())
<< "Entry: " << cdh->file_name_string();
}
}
input_jar.Close();
}
// Verify --java_launcher argument
TEST_F(OutputJarSimpleTest, JavaLauncher) {
std::string out_path = singlejar_test_util::OutputFilePath("out.jar");
const char *launcher_path = DATA_DIR_TOP "src/tools/singlejar/libtest1.jar";
CreateOutput(out_path, "--java_launcher", launcher_path, nullptr);
// check that the offset of the first entry equals launcher size.
InputJar input_jar;
ASSERT_TRUE(input_jar.Open(out_path.c_str()));
const LH *lh;
const CDH *cdh;
cdh = input_jar.NextEntry(&lh);
ASSERT_NE(nullptr, cdh);
struct stat statbuf;
ASSERT_EQ(0, stat(launcher_path, &statbuf));
EXPECT_TRUE(cdh->is());
EXPECT_TRUE(lh->is());
EXPECT_EQ(statbuf.st_size, cdh->local_header_offset());
input_jar.Close();
}
// --main_class option.
TEST_F(OutputJarSimpleTest, MainClass) {
std::string out_path = singlejar_test_util::OutputFilePath("out.jar");
CreateOutput(out_path, "--main_class", "com.google.my.Main", nullptr);
std::string manifest =
singlejar_test_util::GetEntryContents(out_path, "META-INF/MANIFEST.MF");
EXPECT_EQ(
"Manifest-Version: 1.0\r\n"
"Created-By: singlejar\r\n"
"Main-Class: com.google.my.Main\r\n"
"\r\n",
manifest);
}
// --deploy_manifest_lines option.
TEST_F(OutputJarSimpleTest, DeployManifestLines) {
std::string out_path = singlejar_test_util::OutputFilePath("out.jar");
CreateOutput(out_path, "--deploy_manifest_lines", "property1: foo",
"property2: bar", nullptr);
std::string manifest =
singlejar_test_util::GetEntryContents(out_path, "META-INF/MANIFEST.MF");
EXPECT_EQ(
"Manifest-Version: 1.0\r\n"
"Created-By: singlejar\r\n"
"property1: foo\r\n"
"property2: bar\r\n"
"\r\n",
manifest);
}
// --extra_build_info option
TEST_F(OutputJarSimpleTest, ExtraBuildInfo) {
std::string out_path = singlejar_test_util::OutputFilePath("out.jar");
CreateOutput(out_path, "--extra_build_info", "property1=value1",
"--extra_build_info", "property2=value2", nullptr);
std::string build_properties =
singlejar_test_util::GetEntryContents(out_path, "build-data.properties");
EXPECT_PRED2(HasSubstr, build_properties, "\nproperty1=value1\n");
EXPECT_PRED2(HasSubstr, build_properties, "\nproperty2=value2\n");
}
// --build_info_file and --extra_build_info options.
TEST_F(OutputJarSimpleTest, BuildInfoFile) {
std::string build_info_path1 =
singlejar_test_util::OutputFilePath("buildinfo1");
ASSERT_TRUE(blaze::WriteFile("property11=value11\nproperty12=value12\n",
build_info_path1));
std::string build_info_path2 =
singlejar_test_util::OutputFilePath("buildinfo2");
ASSERT_TRUE(blaze::WriteFile("property21=value21\nproperty22=value22\n",
build_info_path2));
std::string out_path = singlejar_test_util::OutputFilePath("out.jar");
CreateOutput(out_path, "--build_info_file", build_info_path1.c_str(),
"--extra_build_info", "property=value", "--build_info_file",
build_info_path2.c_str(), nullptr);
std::string build_properties =
singlejar_test_util::GetEntryContents(out_path, "build-data.properties");
EXPECT_PRED2(HasSubstr, build_properties, "property11=value11\n");
EXPECT_PRED2(HasSubstr, build_properties, "property12=value12\n");
EXPECT_PRED2(HasSubstr, build_properties, "property21=value21\n");
EXPECT_PRED2(HasSubstr, build_properties, "property22=value22\n");
EXPECT_PRED2(HasSubstr, build_properties, "property=value\n");
}
// --resources option.
TEST_F(OutputJarSimpleTest, Resources) {
std::string res11_path = singlejar_test_util::OutputFilePath("res11");
std::string res11_spec = std::string("res1:") + res11_path;
ASSERT_TRUE(blaze::WriteFile("res11.line1\nres11.line2\n", res11_path));
std::string res12_path = singlejar_test_util::OutputFilePath("res12");
std::string res12_spec = std::string("res1:") + res12_path;
ASSERT_TRUE(blaze::WriteFile("res12.line1\nres12.line2\n", res12_path));
std::string res2_path = singlejar_test_util::OutputFilePath("res2");
ASSERT_TRUE(blaze::WriteFile("res2.line1\nres2.line2\n", res2_path));
std::string out_path = singlejar_test_util::OutputFilePath("out.jar");
CreateOutput(out_path, "--resources", res11_spec.c_str(), res12_spec.c_str(),
res2_path.c_str(), nullptr);
// The output should have 'res1' entry containing the concatenation of the
// 'res11' and 'res12' files.
std::string res1 = singlejar_test_util::GetEntryContents(out_path, "res1");
EXPECT_EQ("res11.line1\nres11.line2\nres12.line1\nres12.line2\n", res1);
// The output should have res2 path entry and contents.
std::string res2 = singlejar_test_util::GetEntryContents(out_path, res2_path);
EXPECT_EQ("res2.line1\nres2.line2\n", res2);
}
// --classpath_resources
TEST_F(OutputJarSimpleTest, ClasspathResources) {
std::string res1_path = singlejar_test_util::OutputFilePath("cp_res");
ASSERT_TRUE(blaze::WriteFile("line1\nline2\n", res1_path));
std::string out_path = singlejar_test_util::OutputFilePath("out.jar");
CreateOutput(out_path, "--classpath_resources", res1_path.c_str(), nullptr);
std::string res = singlejar_test_util::GetEntryContents(out_path, "cp_res");
EXPECT_EQ("line1\nline2\n", res);
}
// Duplicate entries for --resources or --classpath_resources
TEST_F(OutputJarSimpleTest, DuplicateResources) {
std::string cp_res_path = singlejar_test_util::OutputFilePath("cp_res");
ASSERT_TRUE(blaze::WriteFile("line1\nline2\n", cp_res_path));
std::string res1_path = singlejar_test_util::OutputFilePath("res1");
std::string res1_spec = "foo:" + res1_path;
ASSERT_TRUE(blaze::WriteFile("resline1\nresline2\n", res1_path));
std::string res2_path = singlejar_test_util::OutputFilePath("res2");
std::string res2_spec = "foo:" + res2_path;
ASSERT_TRUE(blaze::WriteFile("line3\nline4\n", res2_path));
std::string out_path = singlejar_test_util::OutputFilePath("out.jar");
CreateOutput(out_path, "--warn_duplicate_resources", "--resources",
res1_spec.c_str(), res2_spec.c_str(), "--classpath_resources",
cp_res_path.c_str(), cp_res_path.c_str(), nullptr);
std::string cp_res =
singlejar_test_util::GetEntryContents(out_path, "cp_res");
EXPECT_EQ("line1\nline2\n", cp_res);
std::string foo = singlejar_test_util::GetEntryContents(out_path, "foo");
EXPECT_EQ("resline1\nresline2\n", foo);
}
} // namespace