aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/tools/singlejar/output_jar_simple_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/singlejar/output_jar_simple_test.cc')
-rw-r--r--src/tools/singlejar/output_jar_simple_test.cc152
1 files changed, 134 insertions, 18 deletions
diff --git a/src/tools/singlejar/output_jar_simple_test.cc b/src/tools/singlejar/output_jar_simple_test.cc
index ccd22a1a3f..cb7f82baf1 100644
--- a/src/tools/singlejar/output_jar_simple_test.cc
+++ b/src/tools/singlejar/output_jar_simple_test.cc
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <stdlib.h>
+
#include "src/main/cpp/blaze_util.h"
#include "src/main/cpp/util/file.h"
#include "src/main/cpp/util/port.h"
@@ -22,10 +24,17 @@
#include "src/tools/singlejar/test_util.h"
#include "gtest/gtest.h"
+#if !defined(JAR_TOOL_PATH)
+#error "The path to jar tool has to be defined via -DJAR_TOOL_PATH="
+#endif
+
namespace {
+using singlejar_test_util::CreateTextFile;
+using singlejar_test_util::GetEntryContents;
using singlejar_test_util::GetEntryContents;
using singlejar_test_util::OutputFilePath;
+using singlejar_test_util::RunCommand;
using singlejar_test_util::VerifyZip;
using std::string;
@@ -90,6 +99,41 @@ TEST_F(OutputJarSimpleTest, Empty) {
EXPECT_EQ(lh->uncompressed_file_size(), cdh->uncompressed_file_size())
<< "Entry: " << cdh->file_name_string();
}
+ // Verify that each entry has a reasonable timestamp.
+ EXPECT_EQ(lh->last_mod_file_date(), cdh->last_mod_file_date())
+ << "Entry: " << lh->file_name_string();
+ EXPECT_EQ(lh->last_mod_file_time(), cdh->last_mod_file_time())
+ << "Entry: " << lh->file_name_string();
+ uint16_t dos_time = lh->last_mod_file_time();
+ uint16_t dos_date = lh->last_mod_file_date();
+
+ // Current time, rounded to even number of seconds because MSDOS timestamp
+ // does this, too.
+ time_t now = (time(nullptr) + 1) & ~1;
+ struct tm tm_now;
+ localtime_r(&now, &tm_now);
+ char now_time_str[50];
+ strftime(now_time_str, sizeof(now_time_str), "%c", &tm_now);
+
+ // Unpack MSDOS file timestamp. See the comment about its format in
+ // output_jar.cc.
+ struct tm tm;
+ tm.tm_sec = (dos_time & 31) << 1;
+ tm.tm_min = (dos_time >> 5) & 63;
+ tm.tm_hour = (dos_time >> 11) & 31;
+ tm.tm_mday = (dos_date & 31);
+ tm.tm_mon = ((dos_date >> 5) & 15) - 1;
+ tm.tm_year = ((dos_date >> 9) & 127) + 80;
+ tm.tm_isdst = tm_now.tm_isdst;
+ time_t entry_time = mktime(&tm);
+ char entry_time_str[50];
+ strftime(entry_time_str, sizeof(entry_time_str), "%c", &tm);
+
+ // Without --normalize option all the entries should have reasonably
+ // current timestamp (which we arbitrarily choose to be <5 minutes).
+ EXPECT_GE(now, entry_time) << now_time_str << " vs. " << entry_time_str;
+ EXPECT_LE(now, entry_time + 300) << now_time_str << " vs. "
+ << entry_time_str;
}
input_jar.Close();
string manifest = GetEntryContents(out_path, "META-INF/MANIFEST.MF");
@@ -112,6 +156,7 @@ TEST_F(OutputJarSimpleTest, Source) {
ASSERT_TRUE(input_jar.Open(out_path));
const LH *lh;
const CDH *cdh;
+ int file_count = 0;
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.";
@@ -123,7 +168,11 @@ TEST_F(OutputJarSimpleTest, Source) {
EXPECT_EQ(lh->uncompressed_file_size(), cdh->uncompressed_file_size())
<< "Entry: " << cdh->file_name_string();
}
+ if (lh->file_name()[lh->file_name_length() - 1] != '/') {
+ ++file_count;
+ }
}
+ ASSERT_LE(4, file_count);
input_jar.Close();
}
@@ -187,12 +236,11 @@ TEST_F(OutputJarSimpleTest, ExtraBuildInfo) {
// --build_info_file and --extra_build_info options.
TEST_F(OutputJarSimpleTest, BuildInfoFile) {
- string build_info_path1 = OutputFilePath("buildinfo1");
- ASSERT_TRUE(blaze::WriteFile("property11=value11\nproperty12=value12\n",
- build_info_path1));
- string build_info_path2 = OutputFilePath("buildinfo2");
- ASSERT_TRUE(blaze::WriteFile("property21=value21\nproperty22=value22\n",
- build_info_path2));
+ string build_info_path1 =
+ CreateTextFile("buildinfo1", "property11=value11\nproperty12=value12\n");
+ string build_info_path2 =
+ CreateTextFile("buildinfo2", "property21=value21\nproperty22=value22\n");
+
string out_path = OutputFilePath("out.jar");
CreateOutput(out_path, "--build_info_file", build_info_path1.c_str(),
"--extra_build_info", "property=value", "--build_info_file",
@@ -207,16 +255,13 @@ TEST_F(OutputJarSimpleTest, BuildInfoFile) {
// --resources option.
TEST_F(OutputJarSimpleTest, Resources) {
- string res11_path = OutputFilePath("res11");
+ string res11_path = CreateTextFile("res11", "res11.line1\nres11.line2\n");
string res11_spec = string("res1:") + res11_path;
- ASSERT_TRUE(blaze::WriteFile("res11.line1\nres11.line2\n", res11_path));
- string res12_path = OutputFilePath("res12");
+ string res12_path = CreateTextFile("res12", "res12.line1\nres12.line2\n");
string res12_spec = string("res1:") + res12_path;
- ASSERT_TRUE(blaze::WriteFile("res12.line1\nres12.line2\n", res12_path));
- string res2_path = OutputFilePath("res2");
- ASSERT_TRUE(blaze::WriteFile("res2.line1\nres2.line2\n", res2_path));
+ string res2_path = CreateTextFile("res2", "res2.line1\nres2.line2\n");
string out_path = OutputFilePath("out.jar");
CreateOutput(out_path, "--resources", res11_spec.c_str(), res12_spec.c_str(),
@@ -244,16 +289,13 @@ TEST_F(OutputJarSimpleTest, ClasspathResources) {
// Duplicate entries for --resources or --classpath_resources
TEST_F(OutputJarSimpleTest, DuplicateResources) {
- string cp_res_path = OutputFilePath("cp_res");
- ASSERT_TRUE(blaze::WriteFile("line1\nline2\n", cp_res_path));
+ string cp_res_path = CreateTextFile("cp_res", "line1\nline2\n");
- string res1_path = OutputFilePath("res1");
+ string res1_path = CreateTextFile("res1", "resline1\nresline2\n");
string res1_spec = "foo:" + res1_path;
- ASSERT_TRUE(blaze::WriteFile("resline1\nresline2\n", res1_path));
- string res2_path = OutputFilePath("res2");
+ string res2_path = CreateTextFile("res2", "line3\nline4\n");
string res2_spec = "foo:" + res2_path;
- ASSERT_TRUE(blaze::WriteFile("line3\nline4\n", res2_path));
string out_path = OutputFilePath("out.jar");
CreateOutput(out_path, "--warn_duplicate_resources", "--resources",
@@ -308,4 +350,78 @@ TEST_F(OutputJarSimpleTest, IncludeHeaders) {
EXPECT_EQ(expected_entries, jar_entries);
}
+// --normalize
+TEST_F(OutputJarSimpleTest, Normalize) {
+ // Creates output jar containing entries from all possible sources:
+ // * archives created by java_library rule, by jar tool, by zip
+ // * resource files
+ // * classpath resource files
+ // *
+ string out_path = OutputFilePath("out.jar");
+ string testjar_path = OutputFilePath("testinput.jar");
+ {
+ char *jar_tool_path = realpath(JAR_TOOL_PATH, nullptr);
+ string textfile_path = CreateTextFile("jar_testinput.txt", "jar_inputtext");
+ string classfile_path = CreateTextFile("JarTestInput.class", "Dummy");
+ unlink(testjar_path.c_str());
+ ASSERT_EQ(
+ 0, RunCommand(jar_tool_path, "-cf", testjar_path.c_str(),
+ textfile_path.c_str(), classfile_path.c_str(), nullptr));
+ free(jar_tool_path);
+ }
+
+ string testzip_path = OutputFilePath("testinput.zip");
+ {
+ string textfile_path = CreateTextFile("zip_testinput.txt", "zip_inputtext");
+ string classfile_path = CreateTextFile("ZipTestInput.class", "Dummy");
+ unlink(testzip_path.c_str());
+ ASSERT_EQ(
+ 0, RunCommand("zip", "-m", testzip_path.c_str(), textfile_path.c_str(),
+ classfile_path.c_str(), nullptr));
+ }
+
+ string resource_path = CreateTextFile("resource", "resource_text");
+ string cp_resource_path = CreateTextFile("cp_resource", "cp_resource_text");
+
+ // TODO(asmundak): check the following generated entries, too:
+ // * services
+ // * spring.schemas
+ // * spring.handlers
+ // * protobuf.meta
+ // * extra combiner
+
+ CreateOutput(out_path, "--normalize", "--sources",
+ DATA_DIR_TOP "src/tools/singlejar/libtest1.jar",
+ testjar_path.c_str(), testzip_path.c_str(), "--resources",
+ resource_path.c_str(), "--classpath_resources",
+ cp_resource_path.c_str(), nullptr);
+
+ // Scan all entries, verify that *.class entries have timestamp
+ // 01/01/1980 00:00:02 and the rest have the timestamp of 01/01/1980 00:00:00.
+ InputJar input_jar;
+ ASSERT_TRUE(input_jar.Open(out_path));
+ const LH *lh;
+ const CDH *cdh;
+ while ((cdh = input_jar.NextEntry(&lh))) {
+ string entry_name = cdh->file_name_string();
+ EXPECT_EQ(lh->last_mod_file_date(), cdh->last_mod_file_date())
+ << entry_name << " modification date";
+ EXPECT_EQ(lh->last_mod_file_time(), cdh->last_mod_file_time())
+ << entry_name << " modification time";
+ EXPECT_EQ(33, cdh->last_mod_file_date())
+ << entry_name << " modification date should be 01/01/1980";
+ auto n = entry_name.size() - strlen(".class");
+ if (0 == strcmp(entry_name.c_str() + n, ".class")) {
+ EXPECT_EQ(1, cdh->last_mod_file_time())
+ << entry_name
+ << " modification time for .class entry should be 00:00:02";
+ } else {
+ EXPECT_EQ(0, cdh->last_mod_file_time())
+ << entry_name
+ << " modification time for non .class entry should be 00:00:00";
+ }
+ }
+ input_jar.Close();
+}
+
} // namespace