1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format 2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc. All rights reserved. 3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/ 4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without 6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are 7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met: 8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions of source code must retain the above copyright 10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer. 11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions in binary form must reproduce the above 12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer 13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the 14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution. 15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Neither the name of Google Inc. nor the names of its 16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from 17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission. 18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: kenton@google.com (Kenton Varda) 32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Based on original Protocol Buffers design by 33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Sanjay Ghemawat, Jeff Dean, and others. 34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <sys/types.h> 36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <sys/stat.h> 37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <fcntl.h> 38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifdef _MSC_VER 39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <io.h> 40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#else 41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <unistd.h> 42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <vector> 44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor.pb.h> 46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor.h> 47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/zero_copy_stream.h> 48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/command_line_interface.h> 49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/code_generator.h> 50d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <google/protobuf/compiler/mock_code_generator.h> 51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/printer.h> 52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/unittest.pb.h> 53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/testing/file.h> 54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/strutil.h> 55d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <google/protobuf/stubs/substitute.h> 56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/testing/googletest.h> 58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <gtest/gtest.h> 59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google { 61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf { 62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace compiler { 63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#if defined(_WIN32) 65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifndef STDIN_FILENO 66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define STDIN_FILENO 0 67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifndef STDOUT_FILENO 69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define STDOUT_FILENO 1 70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 71d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#ifndef F_OK 72d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#define F_OK 00 // not defined by MSVC for whatever reason 73d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#endif 74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace { 77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass CommandLineInterfaceTest : public testing::Test { 79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville protected: 80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville virtual void SetUp(); 81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville virtual void TearDown(); 82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Runs the CommandLineInterface with the given command line. The 84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // command is automatically split on spaces, and the string "$tmpdir" 85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // is replaced with TestTempDir(). 86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void Run(const string& command); 87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // ----------------------------------------------------------------- 89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Methods to set up the test (called before Run()). 90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville class NullCodeGenerator; 92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 93d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Normally plugins are allowed for all tests. Call this to explicitly 94d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // disable them. 95d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville void DisallowPlugins() { disallow_plugins_ = true; } 96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Create a temp file within temp_directory_ with the given name. 98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The containing directory is also created if necessary. 99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void CreateTempFile(const string& name, const string& contents); 100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 101d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Create a subdirectory within temp_directory_. 102d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville void CreateTempDir(const string& name); 103d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void SetInputsAreProtoPathRelative(bool enable) { 105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cli_.SetInputsAreProtoPathRelative(enable); 106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // ----------------------------------------------------------------- 109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Methods to check the test results (called after Run()). 110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Checks that no text was written to stderr during Run(), and Run() 112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // returned 0. 113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ExpectNoErrors(); 114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Checks that Run() returned non-zero and the stderr output is exactly 116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the text given. expected_test may contain references to "$tmpdir", 117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // which will be replaced by the temporary directory path. 118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ExpectErrorText(const string& expected_text); 119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Checks that Run() returned non-zero and the stderr contains the given 121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // substring. 122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ExpectErrorSubstring(const string& expected_substring); 123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Returns true if ExpectErrorSubstring(expected_substring) would pass, but 125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // does not fail otherwise. 126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool HasAlternateErrorSubstring(const string& expected_substring); 127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Checks that MockCodeGenerator::Generate() was called in the given 129d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // context (or the generator in test_plugin.cc, which produces the same 130d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // output). That is, this tests if the generator with the given name 131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // was called with the given parameter and proto file and produced the 132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // given output file. This is checked by reading the output file and 133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // checking that it contains the content that MockCodeGenerator would 134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // generate given these inputs. message_name is the name of the first 135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // message that appeared in the proto file; this is just to make extra 136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // sure that the correct file was parsed. 137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ExpectGenerated(const string& generator_name, 138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& parameter, 139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& proto_name, 140d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string& message_name); 141d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville void ExpectGenerated(const string& generator_name, 142d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string& parameter, 143d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string& proto_name, 144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& message_name, 145d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string& output_directory); 146d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville void ExpectGeneratedWithInsertions(const string& generator_name, 147d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string& parameter, 148d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string& insertions, 149d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string& proto_name, 150d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string& message_name); 151d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 152d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville void ExpectNullCodeGeneratorCalled(const string& parameter); 153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ReadDescriptorSet(const string& filename, 155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileDescriptorSet* descriptor_set); 156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private: 158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The object we are testing. 159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CommandLineInterface cli_; 160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 161d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Was DisallowPlugins() called? 162d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville bool disallow_plugins_; 163d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We create a directory within TestTempDir() in order to add extra 165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // protection against accidentally deleting user files (since we recursively 166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // delete this directory during the test). This is the full path of that 167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // directory. 168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string temp_directory_; 169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The result of Run(). 171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int return_code_; 172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The captured stderr output. 174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string error_text_; 175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Pointers which need to be deleted later. 177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<CodeGenerator*> mock_generators_to_delete_; 178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 179d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville NullCodeGenerator* null_generator_; 180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass CommandLineInterfaceTest::NullCodeGenerator : public CodeGenerator { 183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public: 184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville NullCodeGenerator() : called_(false) {} 185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ~NullCodeGenerator() {} 186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville mutable bool called_; 188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville mutable string parameter_; 189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // implements CodeGenerator ---------------------------------------- 191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool Generate(const FileDescriptor* file, 192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& parameter, 193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville OutputDirectory* output_directory, 194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string* error) const { 195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville called_ = true; 196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville parameter_ = parameter; 197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CommandLineInterfaceTest::SetUp() { 204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Most of these tests were written before this option was added, so we 205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // run with the option on (which used to be the only way) except in certain 206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // tests where we turn it off. 207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cli_.SetInputsAreProtoPathRelative(true); 208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville temp_directory_ = TestTempDir() + "/proto2_cli_test_temp"; 210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // If the temp directory already exists, it must be left over from a 212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // previous run. Delete it. 213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (File::Exists(temp_directory_)) { 214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville File::DeleteRecursively(temp_directory_, NULL, NULL); 215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Create the temp directory. 218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(File::CreateDir(temp_directory_.c_str(), DEFAULT_FILE_MODE)); 219d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 220d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Register generators. 221d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville CodeGenerator* generator = new MockCodeGenerator("test_generator"); 222d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville mock_generators_to_delete_.push_back(generator); 223d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cli_.RegisterGenerator("--test_out", generator, "Test output."); 224d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cli_.RegisterGenerator("-t", generator, "Test output."); 225d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 226d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator = new MockCodeGenerator("alt_generator"); 227d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville mock_generators_to_delete_.push_back(generator); 228d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cli_.RegisterGenerator("--alt_out", generator, "Alt output."); 229d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 230d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator = null_generator_ = new NullCodeGenerator(); 231d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville mock_generators_to_delete_.push_back(generator); 232d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cli_.RegisterGenerator("--null_out", generator, "Null output."); 233d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 234d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville disallow_plugins_ = false; 235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CommandLineInterfaceTest::TearDown() { 238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Delete the temp directory. 239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville File::DeleteRecursively(temp_directory_, NULL, NULL); 240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Delete all the MockCodeGenerators. 242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < mock_generators_to_delete_.size(); i++) { 243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville delete mock_generators_to_delete_[i]; 244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville mock_generators_to_delete_.clear(); 246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CommandLineInterfaceTest::Run(const string& command) { 249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<string> args; 250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SplitStringUsing(command, " ", &args); 251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 252d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (!disallow_plugins_) { 253d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cli_.AllowPlugins("prefix-"); 254d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 255d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const char* possible_paths[] = { 256d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // When building with shared libraries, libtool hides the real executable 257d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // in .libs and puts a fake wrapper in the current directory. 258d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Unfortunately, due to an apparent bug on Cygwin/MinGW, if one program 259d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // wrapped in this way (e.g. protobuf-tests.exe) tries to execute another 260d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // program wrapped in this way (e.g. test_plugin.exe), the latter fails 261d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // with error code 127 and no explanation message. Presumably the problem 262d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // is that the wrapper for protobuf-tests.exe set some environment 263d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // variables that confuse the wrapper for test_plugin.exe. Luckily, it 264d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // turns out that if we simply invoke the wrapped test_plugin.exe 265d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // directly, it works -- I guess the environment variables set by the 266d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // protobuf-tests.exe wrapper happen to be correct for it too. So we do 267d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // that. 268d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ".libs/test_plugin.exe", // Win32 w/autotool (Cygwin / MinGW) 269d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "test_plugin.exe", // Other Win32 (MSVC) 270d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "test_plugin", // Unix 271d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville }; 272d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 273d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville string plugin_path; 274d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 275d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for (int i = 0; i < GOOGLE_ARRAYSIZE(possible_paths); i++) { 276d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (access(possible_paths[i], F_OK) == 0) { 277d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville plugin_path = possible_paths[i]; 278d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville break; 279d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 280d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 281d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 282d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (plugin_path.empty()) { 283d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville GOOGLE_LOG(ERROR) 284d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville << "Plugin executable not found. Plugin tests are likely to fail."; 285d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else { 286d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville args.push_back("--plugin=prefix-gen-plug=" + plugin_path); 287d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 288d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 289d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville scoped_array<const char*> argv(new const char*[args.size()]); 291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < args.size(); i++) { 293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville args[i] = StringReplace(args[i], "$tmpdir", temp_directory_, true); 294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville argv[i] = args[i].c_str(); 295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CaptureTestStderr(); 298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return_code_ = cli_.Run(args.size(), argv.get()); 300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville error_text_ = GetCapturedTestStderr(); 302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ------------------------------------------------------------------- 305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CommandLineInterfaceTest::CreateTempFile( 307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& name, 308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& contents) { 309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Create parent directory, if necessary. 310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string::size_type slash_pos = name.find_last_of('/'); 311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (slash_pos != string::npos) { 312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string dir = name.substr(0, slash_pos); 313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville File::RecursivelyCreateDir(temp_directory_ + "/" + dir, 0777); 314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Write file. 317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string full_name = temp_directory_ + "/" + name; 318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville File::WriteStringToFileOrDie(contents, full_name); 319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 321d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillevoid CommandLineInterfaceTest::CreateTempDir(const string& name) { 322d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville File::RecursivelyCreateDir(temp_directory_ + "/" + name, 0777); 323d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 324d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ------------------------------------------------------------------- 326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CommandLineInterfaceTest::ExpectNoErrors() { 328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(0, return_code_); 329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ("", error_text_); 330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CommandLineInterfaceTest::ExpectErrorText(const string& expected_text) { 333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_NE(0, return_code_); 334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(StringReplace(expected_text, "$tmpdir", temp_directory_, true), 335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville error_text_); 336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CommandLineInterfaceTest::ExpectErrorSubstring( 339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& expected_substring) { 340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_NE(0, return_code_); 341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring, error_text_); 342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CommandLineInterfaceTest::HasAlternateErrorSubstring( 345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& expected_substring) { 346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_NE(0, return_code_); 347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return error_text_.find(expected_substring) != string::npos; 348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CommandLineInterfaceTest::ExpectGenerated( 351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& generator_name, 352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& parameter, 353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& proto_name, 354d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string& message_name) { 355d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville MockCodeGenerator::ExpectGenerated( 356d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator_name, parameter, "", proto_name, message_name, temp_directory_); 357d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 358d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 359d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillevoid CommandLineInterfaceTest::ExpectGenerated( 360d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string& generator_name, 361d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string& parameter, 362d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string& proto_name, 363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& message_name, 364d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string& output_directory) { 365d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville MockCodeGenerator::ExpectGenerated( 366d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator_name, parameter, "", proto_name, message_name, 367d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville temp_directory_ + "/" + output_directory); 368d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 370d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillevoid CommandLineInterfaceTest::ExpectGeneratedWithInsertions( 371d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string& generator_name, 372d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string& parameter, 373d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string& insertions, 374d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string& proto_name, 375d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string& message_name) { 376d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville MockCodeGenerator::ExpectGenerated( 377d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator_name, parameter, insertions, proto_name, message_name, 378d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville temp_directory_); 379d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 380d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 381d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillevoid CommandLineInterfaceTest::ExpectNullCodeGeneratorCalled( 382d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string& parameter) { 383d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville EXPECT_TRUE(null_generator_->called_); 384d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville EXPECT_EQ(parameter, null_generator_->parameter_); 385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CommandLineInterfaceTest::ReadDescriptorSet( 388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& filename, FileDescriptorSet* descriptor_set) { 389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string path = temp_directory_ + "/" + filename; 390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string file_contents; 391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!File::ReadFileToString(path, &file_contents)) { 392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FAIL() << "File not found: " << path; 393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!descriptor_set->ParseFromString(file_contents)) { 395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FAIL() << "Could not parse file contents: " << path; 396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 401d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleTEST_F(CommandLineInterfaceTest, BasicOutput) { 402d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Test that the common case works. 403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 404d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville CreateTempFile("foo.proto", 405d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "syntax = \"proto2\";\n" 406d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "message Foo {}\n"); 407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 408d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Run("protocol_compiler --test_out=$tmpdir " 409d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--proto_path=$tmpdir foo.proto"); 410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 411d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectNoErrors(); 412d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_generator", "", "foo.proto", "Foo"); 413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 415d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleTEST_F(CommandLineInterfaceTest, BasicPlugin) { 416d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Test that basic plugins work. 417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 418d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville CreateTempFile("foo.proto", 419d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "syntax = \"proto2\";\n" 420d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "message Foo {}\n"); 421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 422d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Run("protocol_compiler --plug_out=$tmpdir " 423d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--proto_path=$tmpdir foo.proto"); 424d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 425d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectNoErrors(); 426d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_plugin", "", "foo.proto", "Foo"); 427d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 428d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 429d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleTEST_F(CommandLineInterfaceTest, GeneratorAndPlugin) { 430d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Invoke a generator and a plugin at the same time. 431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 436d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir " 437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir foo.proto"); 438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectNoErrors(); 440d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_generator", "", "foo.proto", "Foo"); 441d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_plugin", "", "foo.proto", "Foo"); 442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, MultipleInputs) { 445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test parsing multiple input files. 446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 447fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 450fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("bar.proto", 451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 452fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Bar {}\n"); 453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 454d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir " 455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir foo.proto bar.proto"); 456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectNoErrors(); 458d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_generator", "", "foo.proto", "Foo"); 459d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_generator", "", "bar.proto", "Bar"); 460fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, CreateDirectory) { 463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that when we output to a sub-directory, it is created. 464fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 465d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville CreateTempFile("bar/baz/foo.proto", 466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 467fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 468d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville CreateTempDir("out"); 469d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville CreateTempDir("plugout"); 470fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 471d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Run("protocol_compiler --test_out=$tmpdir/out --plug_out=$tmpdir/plugout " 472d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--proto_path=$tmpdir bar/baz/foo.proto"); 473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 474fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectNoErrors(); 475d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_generator", "", "bar/baz/foo.proto", "Foo", "out"); 476d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_plugin", "", "bar/baz/foo.proto", "Foo", "plugout"); 477fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, GeneratorParameters) { 480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that generator parameters are correctly parsed from the command line. 481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 484fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 485fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 486fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=TestParameter:$tmpdir " 487d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--plug_out=TestPluginParameter:$tmpdir " 488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir foo.proto"); 489fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 490fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectNoErrors(); 491d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_generator", "TestParameter", "foo.proto", "Foo"); 492d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_plugin", "TestPluginParameter", "foo.proto", "Foo"); 493d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 494d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 495d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleTEST_F(CommandLineInterfaceTest, Insert) { 496d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Test running a generator that inserts code into another's output. 497d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 498d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville CreateTempFile("foo.proto", 499d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "syntax = \"proto2\";\n" 500d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "message Foo {}\n"); 501d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 502d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Run("protocol_compiler " 503d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--test_out=TestParameter:$tmpdir " 504d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--plug_out=TestPluginParameter:$tmpdir " 505d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--test_out=insert=test_generator,test_plugin:$tmpdir " 506d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--plug_out=insert=test_generator,test_plugin:$tmpdir " 507d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--proto_path=$tmpdir foo.proto"); 508d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 509d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectNoErrors(); 510d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGeneratedWithInsertions( 511d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "test_generator", "TestParameter", "test_generator,test_plugin", 512d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "foo.proto", "Foo"); 513d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGeneratedWithInsertions( 514d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "test_plugin", "TestPluginParameter", "test_generator,test_plugin", 515d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "foo.proto", "Foo"); 516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#if defined(_WIN32) || defined(__CYGWIN__) 519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, WindowsOutputPath) { 521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that the output path can be a Windows-style path. 522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 524fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n"); 525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 526d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Run("protocol_compiler --null_out=C:\\ " 527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir foo.proto"); 528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectNoErrors(); 530d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectNullCodeGeneratorCalled(""); 531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, WindowsOutputPathAndParameter) { 534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that we can have a windows-style output path and a parameter. 535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n"); 538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 539d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Run("protocol_compiler --null_out=bar:C:\\ " 540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir foo.proto"); 541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectNoErrors(); 543d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectNullCodeGeneratorCalled("bar"); 544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 545fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 546fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, TrailingBackslash) { 547fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that the directories can end in backslashes. Some users claim this 548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // doesn't work on their system. 549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 550fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 551fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 552fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 553fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 554fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir\\ " 555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir\\ foo.proto"); 556fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectNoErrors(); 558d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_generator", "", "foo.proto", "Foo"); 559fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 561fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif // defined(_WIN32) || defined(__CYGWIN__) 562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 563fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, PathLookup) { 564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that specifying multiple directories in the proto search path works. 565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 566fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("b/bar.proto", 567fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 568fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Bar {}\n"); 569fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("a/foo.proto", 570fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 571fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "import \"bar.proto\";\n" 572fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {\n" 573fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " optional Bar a = 1;\n" 574fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "}\n"); 575fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("b/foo.proto", "this should not be parsed\n"); 576fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 577fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir " 578fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir/a --proto_path=$tmpdir/b foo.proto"); 579fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 580fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectNoErrors(); 581d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_generator", "", "foo.proto", "Foo"); 582fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 583fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 584fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, ColonDelimitedPath) { 585fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Same as PathLookup, but we provide the proto_path in a single flag. 586fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 587fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("b/bar.proto", 588fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 589fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Bar {}\n"); 590fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("a/foo.proto", 591fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "import \"bar.proto\";\n" 593fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {\n" 594fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " optional Bar a = 1;\n" 595fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "}\n"); 596fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("b/foo.proto", "this should not be parsed\n"); 597fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 598fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#undef PATH_SEPARATOR 599fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#if defined(_WIN32) 600fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define PATH_SEPARATOR ";" 601fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#else 602fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define PATH_SEPARATOR ":" 603fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 605fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir " 606fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir/a"PATH_SEPARATOR"$tmpdir/b foo.proto"); 607fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 608fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#undef PATH_SEPARATOR 609fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 610fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectNoErrors(); 611d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_generator", "", "foo.proto", "Foo"); 612fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 613fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 614fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, NonRootMapping) { 615fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test setting up a search path mapping a directory to a non-root location. 616fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 617fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 618fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 619fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 620fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 621fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir " 622fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=bar=$tmpdir bar/foo.proto"); 623fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 624fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectNoErrors(); 625d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_generator", "", "bar/foo.proto", "Foo"); 626fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 627fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 628fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, MultipleGenerators) { 629fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that we can have multiple generators and use both in one invocation, 630fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // each with a different output directory. 631fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 632fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 633fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 634fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 635fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Create the "a" and "b" sub-directories. 636d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville CreateTempDir("a"); 637d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville CreateTempDir("b"); 638fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 639fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler " 640d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--test_out=$tmpdir/a " 641d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--alt_out=$tmpdir/b " 642fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir foo.proto"); 643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 644fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectNoErrors(); 645d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_generator", "", "foo.proto", "Foo", "a"); 646d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("alt_generator", "", "foo.proto", "Foo", "b"); 647fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 648fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 649fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, DisallowServicesNoServices) { 650fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that --disallow_services doesn't cause a problem when there are no 651fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // services. 652fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 653fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 654fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 655fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 656fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 657fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --disallow_services --test_out=$tmpdir " 658fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir foo.proto"); 659fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 660fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectNoErrors(); 661d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_generator", "", "foo.proto", "Foo"); 662fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 663fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 664fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, DisallowServicesHasService) { 665fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that --disallow_services produces an error when there are services. 666fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 667fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 668fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 669fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n" 670fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "service Bar {}\n"); 671fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 672fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --disallow_services --test_out=$tmpdir " 673fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir foo.proto"); 674fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 675fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorSubstring("foo.proto: This file contains services"); 676fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 677fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 678fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, AllowServicesHasService) { 679fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that services work fine as long as --disallow_services is not used. 680fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 681fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 682fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 683fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n" 684fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "service Bar {}\n"); 685fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 686fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir " 687fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir foo.proto"); 688fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 689fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectNoErrors(); 690d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_generator", "", "foo.proto", "Foo"); 691fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 692fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 693fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, CwdRelativeInputs) { 694fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that we can accept working-directory-relative input files. 695fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 696fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SetInputsAreProtoPathRelative(false); 697fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 698fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 699fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 700fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 701fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 702fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir " 703fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir $tmpdir/foo.proto"); 704fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 705fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectNoErrors(); 706d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_generator", "", "foo.proto", "Foo"); 707fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 708fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 709fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, WriteDescriptorSet) { 710fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 711fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 712fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 713fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("bar.proto", 714fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 715fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "import \"foo.proto\";\n" 716fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Bar {\n" 717fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " optional Foo foo = 1;\n" 718fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "}\n"); 719fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 720fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set " 721fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir bar.proto"); 722fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 723fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectNoErrors(); 724fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 725fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileDescriptorSet descriptor_set; 726fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadDescriptorSet("descriptor_set", &descriptor_set); 727fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (HasFatalFailure()) return; 728fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_EQ(1, descriptor_set.file_size()); 729fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ("bar.proto", descriptor_set.file(0).name()); 730fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 731fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 732fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSet) { 733fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 734fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 735fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 736fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("bar.proto", 737fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 738fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "import \"foo.proto\";\n" 739fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Bar {\n" 740fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " optional Foo foo = 1;\n" 741fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "}\n"); 742fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 743fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set " 744fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--include_imports --proto_path=$tmpdir bar.proto"); 745fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 746fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectNoErrors(); 747fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 748fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileDescriptorSet descriptor_set; 749fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadDescriptorSet("descriptor_set", &descriptor_set); 750fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (HasFatalFailure()) return; 751fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_EQ(2, descriptor_set.file_size()); 752fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (descriptor_set.file(0).name() == "bar.proto") { 753d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville std::swap(descriptor_set.mutable_file()->mutable_data()[0], 754d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville descriptor_set.mutable_file()->mutable_data()[1]); 755fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 756fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ("foo.proto", descriptor_set.file(0).name()); 757fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ("bar.proto", descriptor_set.file(1).name()); 758fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 759fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 760fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ------------------------------------------------------------------- 761fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 762fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, ParseErrors) { 763fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that parse errors are reported. 764fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 765fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 766fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 767fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "badsyntax\n"); 768fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 769fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir " 770fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir foo.proto"); 771fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 772fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorText( 773fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "foo.proto:2:1: Expected top-level statement (e.g. \"message\").\n"); 774fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 775fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 776fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, ParseErrorsMultipleFiles) { 777fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that parse errors are reported from multiple files. 778fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 779fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We set up files such that foo.proto actually depends on bar.proto in 780fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // two ways: Directly and through baz.proto. bar.proto's errors should 781fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // only be reported once. 782fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("bar.proto", 783fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 784fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "badsyntax\n"); 785fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("baz.proto", 786fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 787fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "import \"bar.proto\";\n"); 788fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 789fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 790fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "import \"bar.proto\";\n" 791fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "import \"baz.proto\";\n"); 792fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 793fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir " 794fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir foo.proto"); 795fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 796fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorText( 797fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "bar.proto:2:1: Expected top-level statement (e.g. \"message\").\n" 798fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "baz.proto: Import \"bar.proto\" was not found or had errors.\n" 799fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "foo.proto: Import \"bar.proto\" was not found or had errors.\n" 800fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "foo.proto: Import \"baz.proto\" was not found or had errors.\n"); 801fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 802fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 803fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, InputNotFoundError) { 804fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test what happens if the input file is not found. 805fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 806fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir " 807fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir foo.proto"); 808fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 809fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorText( 810fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "foo.proto: File not found.\n"); 811fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 812fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 813fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundError) { 814fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test what happens when a working-directory-relative input file is not 815fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // found. 816fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 817fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SetInputsAreProtoPathRelative(false); 818fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 819fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir " 820fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir $tmpdir/foo.proto"); 821fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 822fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorText( 823fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "$tmpdir/foo.proto: No such file or directory\n"); 824fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 825fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 826fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, CwdRelativeInputNotMappedError) { 827fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test what happens when a working-directory-relative input file is not 828fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // mapped to a virtual path. 829fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 830fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SetInputsAreProtoPathRelative(false); 831fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 832fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 833fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 834fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 835fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 836fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Create a directory called "bar" so that we can point --proto_path at it. 837fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("bar/dummy", ""); 838fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 839fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir " 840fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir/bar $tmpdir/foo.proto"); 841fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 842fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorText( 843fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "$tmpdir/foo.proto: File does not reside within any path " 844fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "specified using --proto_path (or -I). You must specify a " 845d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--proto_path which encompasses this file. Note that the " 846d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "proto_path must be an exact prefix of the .proto file " 847d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "names -- protoc is too dumb to figure out when two paths " 848d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "(e.g. absolute and relative) are equivalent (it's harder " 849d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "than you think).\n"); 850fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 851fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 852fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundAndNotMappedError) { 853fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Check what happens if the input file is not found *and* is not mapped 854fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // in the proto_path. 855fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 856fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SetInputsAreProtoPathRelative(false); 857fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 858fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Create a directory called "bar" so that we can point --proto_path at it. 859fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("bar/dummy", ""); 860fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 861fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir " 862fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir/bar $tmpdir/foo.proto"); 863fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 864fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorText( 865fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "$tmpdir/foo.proto: No such file or directory\n"); 866fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 867fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 868fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, CwdRelativeInputShadowedError) { 869fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test what happens when a working-directory-relative input file is shadowed 870fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // by another file in the virtual path. 871fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 872fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SetInputsAreProtoPathRelative(false); 873fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 874fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo/foo.proto", 875fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 876fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 877fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("bar/foo.proto", 878fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 879fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Bar {}\n"); 880fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 881fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir " 882fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir/foo --proto_path=$tmpdir/bar " 883fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "$tmpdir/bar/foo.proto"); 884fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 885fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorText( 886fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "$tmpdir/bar/foo.proto: Input is shadowed in the --proto_path " 887fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "by \"$tmpdir/foo/foo.proto\". Either use the latter " 888fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "file as your input or reorder the --proto_path so that the " 889fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "former file's location comes first.\n"); 890fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 891fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 892fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, ProtoPathNotFoundError) { 893fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test what happens if the input file is not found. 894fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 895fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir " 896fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir/foo foo.proto"); 897fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 898fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorText( 899fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "$tmpdir/foo: warning: directory does not exist.\n" 900fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "foo.proto: File not found.\n"); 901fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 902fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 903fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, MissingInputError) { 904fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that we get an error if no inputs are given. 905fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 906fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir " 907fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir"); 908fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 909fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorText("Missing input file.\n"); 910fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 911fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 912fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, MissingOutputError) { 913fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 914fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 915fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 916fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 917fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --proto_path=$tmpdir foo.proto"); 918fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 919fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorText("Missing output directives.\n"); 920fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 921fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 922fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, OutputWriteError) { 923fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 924fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 925fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 926fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 927d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville string output_file = 928d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville MockCodeGenerator::GetOutputFileName("test_generator", "foo.proto"); 929d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 930fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Create a directory blocking our output location. 931d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville CreateTempDir(output_file); 932fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 933fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir " 934fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir foo.proto"); 935fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 936d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // MockCodeGenerator no longer detects an error because we actually write to 937d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // an in-memory location first, then dump to disk at the end. This is no 938d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // big deal. 939d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // ExpectErrorSubstring("MockCodeGenerator detected write error."); 940d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 941fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#if defined(_WIN32) && !defined(__CYGWIN__) 942fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Windows with MSVCRT.dll produces EPERM instead of EISDIR. 943d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (HasAlternateErrorSubstring(output_file + ": Permission denied")) { 944fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return; 945fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 946fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 947fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 948d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectErrorSubstring(output_file + ": Is a directory"); 949fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 950fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 951d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleTEST_F(CommandLineInterfaceTest, PluginOutputWriteError) { 952d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville CreateTempFile("foo.proto", 953d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "syntax = \"proto2\";\n" 954d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "message Foo {}\n"); 955d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 956d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville string output_file = 957d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville MockCodeGenerator::GetOutputFileName("test_plugin", "foo.proto"); 958d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 959d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Create a directory blocking our output location. 960d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville CreateTempDir(output_file); 961d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 962d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Run("protocol_compiler --plug_out=$tmpdir " 963d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--proto_path=$tmpdir foo.proto"); 964d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 965d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#if defined(_WIN32) && !defined(__CYGWIN__) 966d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Windows with MSVCRT.dll produces EPERM instead of EISDIR. 967d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (HasAlternateErrorSubstring(output_file + ": Permission denied")) { 968d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return; 969d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 970d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#endif 971fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 972d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectErrorSubstring(output_file + ": Is a directory"); 973d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 974d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 975d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleTEST_F(CommandLineInterfaceTest, OutputDirectoryNotFoundError) { 976fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 977fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 978fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 979fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 980fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir/nosuchdir " 981fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir foo.proto"); 982fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 983d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectErrorSubstring("nosuchdir/: No such file or directory"); 984fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 985fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 986d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleTEST_F(CommandLineInterfaceTest, PluginOutputDirectoryNotFoundError) { 987d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville CreateTempFile("foo.proto", 988d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "syntax = \"proto2\";\n" 989d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "message Foo {}\n"); 990d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 991d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Run("protocol_compiler --plug_out=$tmpdir/nosuchdir " 992d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--proto_path=$tmpdir foo.proto"); 993fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 994d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectErrorSubstring("nosuchdir/: No such file or directory"); 995d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 996d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 997d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleTEST_F(CommandLineInterfaceTest, OutputDirectoryIsFileError) { 998fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 999fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 1000fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 1001fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1002fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir/foo.proto " 1003fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir foo.proto"); 1004fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1005fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#if defined(_WIN32) && !defined(__CYGWIN__) 1006fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Windows with MSVCRT.dll produces EINVAL instead of ENOTDIR. 1007fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (HasAlternateErrorSubstring("foo.proto/: Invalid argument")) { 1008fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return; 1009fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1010fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 1011fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1012fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorSubstring("foo.proto/: Not a directory"); 1013fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1014fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1015fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, GeneratorError) { 1016d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville CreateTempFile("foo.proto", 1017d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "syntax = \"proto2\";\n" 1018d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "message MockCodeGenerator_Error {}\n"); 1019d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1020d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Run("protocol_compiler --test_out=$tmpdir " 1021d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--proto_path=$tmpdir foo.proto"); 1022d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1023d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectErrorSubstring( 1024d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--test_out: foo.proto: Saw message type MockCodeGenerator_Error."); 1025d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 1026d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1027d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleTEST_F(CommandLineInterfaceTest, GeneratorPluginError) { 1028d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Test a generator plugin that returns an error. 1029fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1030fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 1031fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 1032d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "message MockCodeGenerator_Error {}\n"); 1033fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1034d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Run("protocol_compiler --plug_out=TestParameter:$tmpdir " 1035fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir foo.proto"); 1036fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1037d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectErrorSubstring( 1038d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--plug_out: foo.proto: Saw message type MockCodeGenerator_Error."); 1039fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1040fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1041d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleTEST_F(CommandLineInterfaceTest, GeneratorPluginFail) { 1042d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Test a generator plugin that exits with an error code. 1043fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1044fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 1045fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 1046d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "message MockCodeGenerator_Exit {}\n"); 1047d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1048d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Run("protocol_compiler --plug_out=TestParameter:$tmpdir " 1049d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--proto_path=$tmpdir foo.proto"); 1050d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1051d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectErrorSubstring("Saw message type MockCodeGenerator_Exit."); 1052d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectErrorSubstring( 1053d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--plug_out: prefix-gen-plug: Plugin failed with status code 123."); 1054d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 1055d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1056d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleTEST_F(CommandLineInterfaceTest, GeneratorPluginCrash) { 1057d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Test a generator plugin that crashes. 1058d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1059d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville CreateTempFile("foo.proto", 1060d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "syntax = \"proto2\";\n" 1061d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "message MockCodeGenerator_Abort {}\n"); 1062d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1063d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Run("protocol_compiler --plug_out=TestParameter:$tmpdir " 1064d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--proto_path=$tmpdir foo.proto"); 1065d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1066d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectErrorSubstring("Saw message type MockCodeGenerator_Abort."); 1067d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1068d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#ifdef _WIN32 1069d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Windows doesn't have signals. It looks like abort()ing causes the process 1070d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // to exit with status code 3, but let's not depend on the exact number here. 1071d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectErrorSubstring( 1072d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--plug_out: prefix-gen-plug: Plugin failed with status code"); 1073d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#else 1074d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Don't depend on the exact signal number. 1075d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectErrorSubstring( 1076d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--plug_out: prefix-gen-plug: Plugin killed by signal"); 1077d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#endif 1078d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 1079d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1080d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleTEST_F(CommandLineInterfaceTest, GeneratorPluginNotFound) { 1081d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Test what happens if the plugin isn't found. 1082d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1083d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville CreateTempFile("error.proto", 1084d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "syntax = \"proto2\";\n" 1085d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "message Foo {}\n"); 1086d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1087d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Run("protocol_compiler --badplug_out=TestParameter:$tmpdir " 1088d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--plugin=prefix-gen-badplug=no_such_file " 1089d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--proto_path=$tmpdir error.proto"); 1090d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1091d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#ifdef _WIN32 1092d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectErrorSubstring( 1093d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--badplug_out: prefix-gen-badplug: The system cannot find the file " 1094d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "specified."); 1095d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#else 1096d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Error written to stdout by child process after exec() fails. 1097d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectErrorSubstring( 1098d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "no_such_file: program not found or is not executable"); 1099d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1100d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Error written by parent process when child fails. 1101d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectErrorSubstring( 1102d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--badplug_out: prefix-gen-badplug: Plugin failed with status code 1."); 1103d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#endif 1104d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 1105d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1106d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleTEST_F(CommandLineInterfaceTest, GeneratorPluginNotAllowed) { 1107d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Test what happens if plugins aren't allowed. 1108d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1109d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville CreateTempFile("error.proto", 1110d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "syntax = \"proto2\";\n" 1111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 1112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1113d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville DisallowPlugins(); 1114d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Run("protocol_compiler --plug_out=TestParameter:$tmpdir " 1115d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "--proto_path=$tmpdir error.proto"); 1116d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1117d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectErrorSubstring("Unknown flag: --plug_out"); 1118d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 1119d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1120d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleTEST_F(CommandLineInterfaceTest, HelpText) { 1121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("test_exec_name --help"); 1122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorSubstring("Usage: test_exec_name "); 1124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorSubstring("--test_out=OUT_DIR"); 1125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorSubstring("Test output."); 1126d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectErrorSubstring("--alt_out=OUT_DIR"); 1127d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectErrorSubstring("Alt output."); 1128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, GccFormatErrors) { 1131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test --error_format=gcc (which is the default, but we want to verify 1132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // that it can be set explicitly). 1133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 1135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 1136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "badsyntax\n"); 1137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir " 1139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir --error_format=gcc foo.proto"); 1140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorText( 1142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "foo.proto:2:1: Expected top-level statement (e.g. \"message\").\n"); 1143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, MsvsFormatErrors) { 1146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test --error_format=msvs 1147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 1149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 1150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "badsyntax\n"); 1151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir " 1153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir --error_format=msvs foo.proto"); 1154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorText( 1156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "foo.proto(2) : error in column=1: Expected top-level statement " 1157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "(e.g. \"message\").\n"); 1158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, InvalidErrorFormat) { 1161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test --error_format=msvs 1162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 1164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 1165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "badsyntax\n"); 1166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out=$tmpdir " 1168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir --error_format=invalid foo.proto"); 1169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorText( 1171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Unknown error format: invalid\n"); 1172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ------------------------------------------------------------------- 1175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Flag parsing tests 1176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, ParseSingleCharacterFlag) { 1178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that a single-character flag works. 1179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 1181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 1182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 1183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler -t$tmpdir " 1185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir foo.proto"); 1186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectNoErrors(); 1188d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_generator", "", "foo.proto", "Foo"); 1189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, ParseSpaceDelimitedValue) { 1192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that separating the flag value with a space works. 1193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 1195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 1196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 1197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out $tmpdir " 1199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir foo.proto"); 1200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectNoErrors(); 1202d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_generator", "", "foo.proto", "Foo"); 1203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, ParseSingleCharacterSpaceDelimitedValue) { 1206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that separating the flag value with a space works for 1207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // single-character flags. 1208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CreateTempFile("foo.proto", 1210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 1211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 1212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler -t $tmpdir " 1214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--proto_path=$tmpdir foo.proto"); 1215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectNoErrors(); 1217d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ExpectGenerated("test_generator", "", "foo.proto", "Foo"); 1218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, MissingValueError) { 1221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that we get an error if a flag is missing its value. 1222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out --proto_path=$tmpdir foo.proto"); 1224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorText("Missing value for flag: --test_out\n"); 1226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(CommandLineInterfaceTest, MissingValueAtEndError) { 1229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that we get an error if the last argument is a flag requiring a 1230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // value. 1231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Run("protocol_compiler --test_out"); 1233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectErrorText("Missing value for flag: --test_out\n"); 1235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 1238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Test for --encode and --decode. Note that it would be easier to do this 1240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// test as a shell script, but we'd like to be able to run the test on 1241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// platforms that don't have a Bourne-compatible shell available (especially 1242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Windows/MSVC). 1243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass EncodeDecodeTest : public testing::Test { 1244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville protected: 1245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville virtual void SetUp() { 1246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville duped_stdin_ = dup(STDIN_FILENO); 1247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville virtual void TearDown() { 1250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dup2(duped_stdin_, STDIN_FILENO); 1251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville close(duped_stdin_); 1252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void RedirectStdinFromText(const string& input) { 1255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string filename = TestTempDir() + "/test_stdin"; 1256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville File::WriteStringToFileOrDie(input, filename); 1257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(RedirectStdinFromFile(filename)); 1258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool RedirectStdinFromFile(const string& filename) { 1261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int fd = open(filename.c_str(), O_RDONLY); 1262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (fd < 0) return false; 1263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dup2(fd, STDIN_FILENO); 1264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville close(fd); 1265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 1266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Remove '\r' characters from text. 1269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string StripCR(const string& text) { 1270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string result; 1271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < text.size(); i++) { 1273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (text[i] != '\r') { 1274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.push_back(text[i]); 1275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 1279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville enum Type { TEXT, BINARY }; 1282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville enum ReturnCode { SUCCESS, ERROR }; 1283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool Run(const string& command) { 1285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<string> args; 1286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville args.push_back("protoc"); 1287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SplitStringUsing(command, " ", &args); 1288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville args.push_back("--proto_path=" + TestSourceDir()); 1289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville scoped_array<const char*> argv(new const char*[args.size()]); 1291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < args.size(); i++) { 1292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville argv[i] = args[i].c_str(); 1293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CommandLineInterface cli; 1296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cli.SetInputsAreProtoPathRelative(true); 1297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CaptureTestStdout(); 1299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CaptureTestStderr(); 1300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int result = cli.Run(args.size(), argv.get()); 1302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville captured_stdout_ = GetCapturedTestStdout(); 1304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville captured_stderr_ = GetCapturedTestStderr(); 1305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result == 0; 1307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ExpectStdoutMatchesBinaryFile(const string& filename) { 1310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string expected_output; 1311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_TRUE(File::ReadFileToString(filename, &expected_output)); 1312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Don't use EXPECT_EQ because we don't want to print raw binary data to 1314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // stdout on failure. 1315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(captured_stdout_ == expected_output); 1316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ExpectStdoutMatchesTextFile(const string& filename) { 1319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string expected_output; 1320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_TRUE(File::ReadFileToString(filename, &expected_output)); 1321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectStdoutMatchesText(expected_output); 1323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ExpectStdoutMatchesText(const string& expected_text) { 1326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(StripCR(expected_text), StripCR(captured_stdout_)); 1327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ExpectStderrMatchesText(const string& expected_text) { 1330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(StripCR(expected_text), StripCR(captured_stderr_)); 1331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private: 1334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int duped_stdin_; 1335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string captured_stdout_; 1336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string captured_stderr_; 1337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 1338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(EncodeDecodeTest, Encode) { 1340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville RedirectStdinFromFile(TestSourceDir() + 1341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "/google/protobuf/testdata/text_format_unittest_data.txt"); 1342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(Run("google/protobuf/unittest.proto " 1343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--encode=protobuf_unittest.TestAllTypes")); 1344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectStdoutMatchesBinaryFile(TestSourceDir() + 1345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "/google/protobuf/testdata/golden_message"); 1346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectStderrMatchesText(""); 1347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(EncodeDecodeTest, Decode) { 1350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville RedirectStdinFromFile(TestSourceDir() + 1351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "/google/protobuf/testdata/golden_message"); 1352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(Run("google/protobuf/unittest.proto " 1353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--decode=protobuf_unittest.TestAllTypes")); 1354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectStdoutMatchesTextFile(TestSourceDir() + 1355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "/google/protobuf/testdata/text_format_unittest_data.txt"); 1356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectStderrMatchesText(""); 1357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(EncodeDecodeTest, Partial) { 1360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville RedirectStdinFromText(""); 1361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(Run("google/protobuf/unittest.proto " 1362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--encode=protobuf_unittest.TestRequired")); 1363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectStdoutMatchesText(""); 1364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectStderrMatchesText( 1365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "warning: Input message is missing required fields: a, b, c\n"); 1366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(EncodeDecodeTest, DecodeRaw) { 1369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville protobuf_unittest::TestAllTypes message; 1370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message.set_optional_int32(123); 1371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message.set_optional_string("foo"); 1372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string data; 1373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message.SerializeToString(&data); 1374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville RedirectStdinFromText(data); 1376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(Run("--decode_raw")); 1377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectStdoutMatchesText("1: 123\n" 1378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "14: \"foo\"\n"); 1379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectStderrMatchesText(""); 1380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(EncodeDecodeTest, UnknownType) { 1383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_FALSE(Run("google/protobuf/unittest.proto " 1384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--encode=NoSuchType")); 1385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectStdoutMatchesText(""); 1386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectStderrMatchesText("Type not defined: NoSuchType\n"); 1387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(EncodeDecodeTest, ProtoParseError) { 1390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_FALSE(Run("google/protobuf/no_such_file.proto " 1391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "--encode=NoSuchType")); 1392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectStdoutMatchesText(""); 1393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectStderrMatchesText( 1394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "google/protobuf/no_such_file.proto: File not found.\n"); 1395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // anonymous namespace 1398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace compiler 1400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace protobuf 1401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace google 1402