From 95785a8675957fa0b96112f0e9835bc222b3b276 Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Mon, 25 Sep 2017 11:19:33 -0700 Subject: [PATCH] Bug 1402151, part 9 - Implement gtest for FTP directory listing parsing. r=michal This test turns the existing stand alone test for the FTP directory listing parser into a gtest. MozReview-Commit-ID: 7n60TfcTXTJ --HG-- extra : rebase_source : 79c88708a9bf9bee6c27a82f2c93a95016e063dd --- .../streamconv/converters/ParseFTPList.cpp | 204 ------------------ netwerk/test/gtest/moz.build | 4 + .../test/gtest/parse-ftp/TestParseFTPList.cpp | 169 +++++++++++++++ netwerk/test/gtest/parse-ftp/moz.build | 68 ++++++ testing/cppunittest.ini | 1 + 5 files changed, 242 insertions(+), 204 deletions(-) create mode 100644 netwerk/test/gtest/parse-ftp/TestParseFTPList.cpp create mode 100644 netwerk/test/gtest/parse-ftp/moz.build diff --git a/netwerk/streamconv/converters/ParseFTPList.cpp b/netwerk/streamconv/converters/ParseFTPList.cpp index 402af60aff8a..eaf783cfc632 100644 --- a/netwerk/streamconv/converters/ParseFTPList.cpp +++ b/netwerk/streamconv/converters/ParseFTPList.cpp @@ -1665,207 +1665,3 @@ int ParseFTPList(const char *line, struct list_state *state, return ParsingFailed(state); } -/* ==================================================================== */ -/* standalone testing */ -/* ==================================================================== */ -#if 0 - -#include - -static int do_it(FILE *outfile, - char *line, size_t linelen, struct list_state *state, - char **cmnt_buf, unsigned int *cmnt_buf_sz, - char **list_buf, unsigned int *list_buf_sz ) -{ - struct list_result result; - char *p; - int rc; - - rc = ParseFTPList( line, state, &result ); - - if (!outfile) - { - outfile = stdout; - if (rc == '?') - fprintf(outfile, "junk: %.*s\n", (int)linelen, line ); - else if (rc == '"') - fprintf(outfile, "cmnt: %.*s\n", (int)linelen, line ); - else - fprintf(outfile, - "list: %02u-%02u-%02u %02u:%02u%cM %20s %.*s%s%.*s\n", - (result.fe_time.tm_mday ? (result.fe_time.tm_month + 1) : 0), - result.fe_time.tm_mday, - (result.fe_time.tm_mday ? (result.fe_time.tm_year % 100) : 0), - result.fe_time.tm_hour - - ((result.fe_time.tm_hour > 12)?(12):(0)), - result.fe_time.tm_min, - ((result.fe_time.tm_hour >= 12) ? 'P' : 'A'), - (rc == 'd' ? " " : - (rc == 'l' ? " " : result.fe_size)), - (int)result.fe_fnlen, result.fe_fname, - ((rc == 'l' && result.fe_lnlen) ? " -> " : ""), - (int)((rc == 'l' && result.fe_lnlen) ? result.fe_lnlen : 0), - ((rc == 'l' && result.fe_lnlen) ? result.fe_lname : "") ); - } - else if (rc != '?') /* NOT junk */ - { - char **bufp = list_buf; - unsigned int *bufz = list_buf_sz; - - if (rc == '"') /* comment - make it a 'result' */ - { - memset( &result, 0, sizeof(result)); - result.fe_fname = line; - result.fe_fnlen = linelen; - result.fe_type = 'f'; - if (line[linelen-1] == '/') - { - result.fe_type = 'd'; - result.fe_fnlen--; - } - bufp = cmnt_buf; - bufz = cmnt_buf_sz; - rc = result.fe_type; - } - - linelen = 80 + result.fe_fnlen + result.fe_lnlen; - p = (char *)realloc( *bufp, *bufz + linelen ); - if (!p) - return -1; - sprintf( &p[*bufz], - "%02u-%02u-%04u %02u:%02u:%02u %20s %.*s%s%.*s\n", - (result.fe_time.tm_mday ? (result.fe_time.tm_month + 1) : 0), - result.fe_time.tm_mday, - (result.fe_time.tm_mday ? (result.fe_time.tm_year + 1900) : 0), - result.fe_time.tm_hour, - result.fe_time.tm_min, - result.fe_time.tm_sec, - (rc == 'd' ? " " : - (rc == 'l' ? " " : result.fe_size)), - (int)result.fe_fnlen, result.fe_fname, - ((rc == 'l' && result.fe_lnlen) ? " -> " : ""), - (int)((rc == 'l' && result.fe_lnlen) ? result.fe_lnlen : 0), - ((rc == 'l' && result.fe_lnlen) ? result.fe_lname : "") ); - linelen = strlen(&p[*bufz]); - *bufp = p; - *bufz = *bufz + linelen; - } - return 0; -} - -int main(int argc, char *argv[]) -{ - FILE *infile = (FILE *)0; - FILE *outfile = (FILE *)0; - int need_close_in = 0; - int need_close_out = 0; - - if (argc > 1) - { - infile = stdin; - if (strcmp(argv[1], "-") == 0) - need_close_in = 0; - else if ((infile = fopen(argv[1], "r")) != ((FILE *)0)) - need_close_in = 1; - else - fprintf(stderr, "Unable to open input file '%s'\n", argv[1]); - } - if (infile && argc > 2) - { - outfile = stdout; - if (strcmp(argv[2], "-") == 0) - need_close_out = 0; - else if ((outfile = fopen(argv[2], "w")) != ((FILE *)0)) - need_close_out = 1; - else - { - fprintf(stderr, "Unable to open output file '%s'\n", argv[2]); - fclose(infile); - infile = (FILE *)0; - } - } - - if (!infile) - { - char *appname = &(argv[0][strlen(argv[0])]); - while (appname > argv[0]) - { - appname--; - if (*appname == '/' || *appname == '\\' || *appname == ':') - { - appname++; - break; - } - } - fprintf(stderr, - "Usage: %s []\n" - "\nIf an outout file is specified the results will be" - "\nbe post-processed, and only the file entries will appear" - "\n(or all comments if there are no file entries)." - "\nNot specifying an output file causes %s to run in \"debug\"" - "\nmode, ie results are printed as lines are parsed." - "\nIf a filename is a single dash ('-'), stdin/stdout is used." - "\n", appname, appname ); - } - else - { - char *cmnt_buf = (char *)0; - unsigned int cmnt_buf_sz = 0; - char *list_buf = (char *)0; - unsigned int list_buf_sz = 0; - - struct list_state state; - char line[512]; - - memset( &state, 0, sizeof(state) ); - while (fgets(line, sizeof(line), infile)) - { - size_t linelen = strlen(line); - if (linelen < (sizeof(line)-1)) - { - if (linelen > 0 && line[linelen-1] == '\n') - linelen--; - if (do_it( outfile, line, linelen, &state, - &cmnt_buf, &cmnt_buf_sz, &list_buf, &list_buf_sz) != 0) - { - fprintf(stderr, "Insufficient memory. Listing may be incomplete.\n"); - break; - } - } - else - { - /* no '\n' found. drop this and everything up to the next '\n' */ - fprintf(stderr, "drop: %.*s", (int)linelen, line ); - while (linelen == sizeof(line)) - { - if (!fgets(line, sizeof(line), infile)) - break; - linelen = 0; - while (linelen < sizeof(line) && line[linelen] != '\n') - linelen++; - fprintf(stderr, "%.*s", (int)linelen, line ); - } - fprintf(stderr, "\n"); - } - } - if (outfile) - { - if (list_buf) - fwrite( list_buf, 1, list_buf_sz, outfile ); - else if (cmnt_buf) - fwrite( cmnt_buf, 1, cmnt_buf_sz, outfile ); - } - if (list_buf) - free(list_buf); - if (cmnt_buf) - free(cmnt_buf); - - if (need_close_in) - fclose(infile); - if (outfile && need_close_out) - fclose(outfile); - } - - return 0; -} -#endif diff --git a/netwerk/test/gtest/moz.build b/netwerk/test/gtest/moz.build index 306c22cce931..95927269b2be 100644 --- a/netwerk/test/gtest/moz.build +++ b/netwerk/test/gtest/moz.build @@ -13,6 +13,10 @@ UNIFIED_SOURCES += [ 'TestStandardURL.cpp', ] +TEST_DIRS += [ + 'parse-ftp', +] + include('/ipc/chromium/chromium-config.mozbuild') FINAL_LIBRARY = 'xul-gtest' diff --git a/netwerk/test/gtest/parse-ftp/TestParseFTPList.cpp b/netwerk/test/gtest/parse-ftp/TestParseFTPList.cpp new file mode 100644 index 000000000000..bd8277332779 --- /dev/null +++ b/netwerk/test/gtest/parse-ftp/TestParseFTPList.cpp @@ -0,0 +1,169 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" +#include "mozilla/ArrayUtils.h" +#include "nsPrintfCString.h" +#include + +#include "ParseFTPList.h" + + +PRTime gTestTime = 0; + +// Pretend this is the current time for the purpose of running the +// test. The day and year matter because they are used to figure out a +// default value when no year is specified. Tests will fail if this is +// changed too much. +const char* kDefaultTestTime = "01-Aug-2002 00:00:00 GMT"; + +static PRTime +TestTime() +{ + return gTestTime; +} + +static void +ParseFTPLine(char* inputLine, + FILE* resultFile, + list_state* state) +{ + struct list_result result; + int rc = ParseFTPList(inputLine, state, &result, PR_GMTParameters, TestTime); + + if (rc == '?' || rc == '"') { + // Ignore junk and comments. + return; + } + + if (!resultFile) { + // No result file was passed in, so there's nothing to check. + return; + } + + char resultLine[512]; + ASSERT_NE(fgets(resultLine, sizeof(resultLine), resultFile), nullptr); + + nsPrintfCString parsed("%02u-%02u-%04u %02u:%02u:%02u %20s %.*s%s%.*s\n", + (result.fe_time.tm_mday ? (result.fe_time.tm_month + 1) : 0), + result.fe_time.tm_mday, + (result.fe_time.tm_mday ? result.fe_time.tm_year : 0), + result.fe_time.tm_hour, + result.fe_time.tm_min, + result.fe_time.tm_sec, + (rc == 'd' ? " " : + (rc == 'l' ? " " : result.fe_size)), + (int)result.fe_fnlen, result.fe_fname, + ((rc == 'l' && result.fe_lnlen) ? " -> " : ""), + (int)((rc == 'l' && result.fe_lnlen) ? result.fe_lnlen : 0), + ((rc == 'l' && result.fe_lnlen) ? result.fe_lname : "")); + + ASSERT_STREQ(parsed.get(), resultLine); +} + +FILE* +OpenResultFile(const char* resultFileName) +{ + if (!resultFileName) { + return nullptr; + } + + FILE* resultFile = fopen(resultFileName, "r"); + EXPECT_NE(resultFile, nullptr); + + // Ignore anything in the expected result file before and including the first blank line. + char resultLine[512]; + while (fgets(resultLine, sizeof(resultLine), resultFile)) { + size_t lineLen = strlen(resultLine); + EXPECT_LT(lineLen, sizeof(resultLine) - 1); + if (lineLen > 0 && resultLine[lineLen - 1] == '\n') { + lineLen--; + } + if (lineLen == 0) { + break; + } + } + + // There must be a blank line somewhere in the result file. + EXPECT_EQ(strcmp(resultLine, "\n"), 0); + + return resultFile; +} + +void +ParseFTPFile(const char* inputFileName, + const char* resultFileName) +{ + printf("Checking %s\n", inputFileName); + FILE* inFile = fopen(inputFileName, "r"); + ASSERT_NE(inFile, nullptr); + + FILE* resultFile = OpenResultFile(resultFileName); + + char inputLine[512]; + struct list_state state; + memset(&state, 0, sizeof(state)); + while (fgets(inputLine, sizeof(inputLine), inFile)) { + size_t lineLen = strlen(inputLine); + EXPECT_LT(lineLen, sizeof(inputLine) - 1); + if (lineLen > 0 && inputLine[lineLen - 1] == '\n') { + lineLen--; + } + + ParseFTPLine(inputLine, resultFile, &state); + } + + // Make sure there are no extra lines in the result file. + if (resultFile) { + char resultLine[512]; + EXPECT_EQ(fgets(resultLine, sizeof(resultLine), resultFile), nullptr) << + "There should not be more lines in the expected results file than in the parser output."; + fclose(resultFile); + } + + fclose(inFile); +} + +static const char* testFiles[] = { + "3-guess", + "C-VMold", + "C-zVM", + "D-WinNT", + "E-EPLF", + "O-guess", + "R-dls", + "U-HellSoft", + "U-hethmon", + "U-murksw", + "U-ncFTPd", + "U-NetPresenz", + "U-NetWare", + "U-nogid", + "U-no_ug", + "U-Novonyx", + "U-proftpd", + "U-Surge", + "U-WarFTPd", + "U-WebStar", + "U-WinNT", + "U-wu", + "V-MultiNet", + "V-VMS-mix", +}; + +TEST(ParseFTPTest, Check) +{ + PRStatus result = PR_ParseTimeString(kDefaultTestTime, true, &gTestTime); + ASSERT_EQ(PR_SUCCESS, result); + + char inputFileName[200]; + char resultFileName[200]; + for (size_t test = 0; test < mozilla::ArrayLength(testFiles); ++test) { + snprintf(inputFileName, mozilla::ArrayLength(inputFileName), "%s.in", testFiles[test]); + snprintf(resultFileName, mozilla::ArrayLength(inputFileName), "%s.out", testFiles[test]); + ParseFTPFile(inputFileName, resultFileName); + } +} + diff --git a/netwerk/test/gtest/parse-ftp/moz.build b/netwerk/test/gtest/parse-ftp/moz.build new file mode 100644 index 000000000000..15b2a59a6ae4 --- /dev/null +++ b/netwerk/test/gtest/parse-ftp/moz.build @@ -0,0 +1,68 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +UNIFIED_SOURCES += [ + 'TestParseFTPList.cpp', +] + +TEST_HARNESS_FILES.gtest += [ + '3-guess.in', + '3-guess.out', + 'C-VMold.in', + 'C-VMold.out', + 'C-zVM.in', + 'C-zVM.out', + 'D-WinNT.in', + 'D-WinNT.out', + 'E-EPLF.in', + 'E-EPLF.out', + 'O-guess.in', + 'O-guess.out', + 'R-dls.in', + 'R-dls.out', + 'U-HellSoft.in', + 'U-HellSoft.out', + 'U-hethmon.in', + 'U-hethmon.out', + 'U-murksw.in', + 'U-murksw.out', + 'U-ncFTPd.in', + 'U-ncFTPd.out', + 'U-NetPresenz.in', + 'U-NetPresenz.out', + 'U-NetWare.in', + 'U-NetWare.out', + 'U-no_ug.in', + 'U-no_ug.out', + 'U-nogid.in', + 'U-nogid.out', + 'U-Novonyx.in', + 'U-Novonyx.out', + 'U-proftpd.in', + 'U-proftpd.out', + 'U-Surge.in', + 'U-Surge.out', + 'U-WarFTPd.in', + 'U-WarFTPd.out', + 'U-WebStar.in', + 'U-WebStar.out', + 'U-WinNT.in', + 'U-WinNT.out', + 'U-wu.in', + 'U-wu.out', + 'V-MultiNet.in', + 'V-MultiNet.out', + 'V-VMS-mix.in', + 'V-VMS-mix.out', +] + +include('/ipc/chromium/chromium-config.mozbuild') + +LOCAL_INCLUDES += [ + '/netwerk/streamconv/converters', +] + +FINAL_LIBRARY = 'xul-gtest' diff --git a/testing/cppunittest.ini b/testing/cppunittest.ini index b5d83247092e..a38d18befbba 100644 --- a/testing/cppunittest.ini +++ b/testing/cppunittest.ini @@ -28,6 +28,7 @@ skip-if = os != 'win' [TestMacroForEach] [TestMathAlgorithms] [TestMaybe] +[TestParseFTPList] [TestPLDHash] skip-if = os == 'b2g' #Bug 1038197 [TestPair]