mirror of
https://github.com/valitydev/thrift.git
synced 2024-11-07 02:45:22 +00:00
262cfb4189
.thrift files Client: Compiler (general) Patch: Sanjay Poojary <sanjay.poojary@ni.com>, Ben Craig <bencraig@apache.org>, and Zach Hindes <zach.hindes@ni.com> This closes #541
262 lines
8.7 KiB
Perl
262 lines
8.7 KiB
Perl
#!/usr/bin/perl -w
|
|
|
|
# Licensed to the Apache Software Foundation (ASF) under one
|
|
# or more contributor license agreements. See the NOTICE file
|
|
# distributed with this work for additional information
|
|
# regarding copyright ownership. The ASF licenses this file
|
|
# to you under the Apache License, Version 2.0 (the
|
|
# "License"); you may not use this file except in compliance
|
|
# with the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing,
|
|
# software distributed under the License is distributed on an
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
# KIND, either express or implied. See the License for the
|
|
# specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
|
|
#break1 - Thrift method removed from service base
|
|
#break2 - Struct field changed in test_struct1(i16 to i32)
|
|
#break3 - Struct field changed in test_struct1(enum1 to enum2)
|
|
#break4 - Field type changed in test_struct1(bool to string)
|
|
#break5- member field type changed in test_struct1(bool to list<bool>)
|
|
#break6- Field type changed in test_struct2 (list<double> to list<i16>)
|
|
#break7 - requiredness removed in struct6
|
|
#break8 - requiredness addedd in struct5
|
|
#break9 - Struct field removed from struct1
|
|
#break10 - Struct field removed from struct2 id = 1
|
|
#break11 - Struct field removed from struct3 last id
|
|
#break12 - derived1_function1 return type changed from enum1 to enum2
|
|
#break13 - derived1_function6 return type changed from struct1 to struct2
|
|
#break14 - derived1_function4 return type changed from string to double
|
|
#break15 - derived2_function1 return type changed from list<i32> to list<i16>
|
|
#break16 - derived2_function5 return type changed from map<test_enum1,test_enum2> to map<test_enum3, test_enum2>
|
|
#break17 - derived2_function6 return type changed from map<struct1,struct2> to map<struct1, struct3>
|
|
#break18- oneway removed from base_oneway
|
|
#break19 - oneway added to base_function1
|
|
#break20 - first enum value removed from enum1
|
|
#break21- last enum value removed from enum2
|
|
#break22 - in-between enum value removed from enum1
|
|
#break23 - required struct field added to struct4
|
|
#break24 - removed inheritance of derived1.
|
|
#break25 - changed inheritance of derived2.
|
|
#break26 - Field type changed in base_function1 argument id=3
|
|
#break27 - argument changed base_function2 list<enum1> to list<enum3> id =8
|
|
#break28- derived1_function5 arguement type changed map<i64, double> to list<i64>
|
|
#break29 - base_function2 arguemnt type changed list<string> to string
|
|
#break30- derived1_function6 argument changed struct1 to map<struct1,struct1>
|
|
#break31 - Exception removed to base_function2
|
|
#break32- Exception1 field type changed for id =1
|
|
#break33 - derived1_function1 exception type changed.
|
|
#break34 - Field added to struct with Field ID being in between two existing field IDs
|
|
|
|
#warning.thrift
|
|
#Changing defaults
|
|
#Id=1 struct5
|
|
#id=2 struct5
|
|
#id=4 struct2(list<double>)
|
|
#id=3 struct2(list<i64> default values removed)
|
|
#id 4 struct1 change in double value
|
|
#id 5 struct1 (default string value removed)
|
|
#id=1 struct3 (change in map values)
|
|
#id2 struct3 (change in map keys)
|
|
|
|
#change in inheritance for derived1 and derived2
|
|
|
|
#change in struct field names
|
|
#id9 struct1
|
|
#id2 struct2
|
|
|
|
use strict;
|
|
use warnings;
|
|
use Getopt::Std;
|
|
|
|
# globals
|
|
my $gArguments = ""; # arguments that will be passed to AuditTool
|
|
my $gAuditToolPath = "";
|
|
my $gPreviousThriftPath; # previous thrift path
|
|
my $gCurrentThriftPath; # current thrift path
|
|
my $gThriftFileFolder;
|
|
my $gBreakingFilesCount =34;
|
|
|
|
my $gVerbose = 0;
|
|
#functions
|
|
sub auditBreakingChanges;
|
|
sub auditNonBreakingChanges;
|
|
|
|
main();
|
|
|
|
sub main
|
|
{
|
|
parseOptions();
|
|
auditBreakingChanges();
|
|
auditNonBreakingChanges();
|
|
}
|
|
|
|
sub parseOptions
|
|
{
|
|
my %options = ();
|
|
if ( getopts ('vf:o:t:',\%options) )
|
|
{
|
|
# current (new) thrift folder
|
|
if ($options{'f'})
|
|
{
|
|
$gThriftFileFolder = $options{'f'};
|
|
$gPreviousThriftPath = $gThriftFileFolder."/test.thrift";
|
|
}
|
|
else
|
|
{
|
|
die "Missing Folder containing thrift files\n";
|
|
}
|
|
|
|
if($options{'t'})
|
|
{
|
|
$gAuditToolPath = $options{'t'};
|
|
}
|
|
else
|
|
{
|
|
die "Audit Tool Path required \n";
|
|
}
|
|
|
|
if ($options{'v'})
|
|
{
|
|
$gVerbose = 1;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
sub auditBreakingChanges
|
|
{
|
|
my $breakingFileBaseName = $gThriftFileFolder."/break";
|
|
my $newThriftFile;
|
|
for(my $i=1; $i <= $gBreakingFilesCount; $i++)
|
|
{
|
|
$newThriftFile = $breakingFileBaseName."$i.thrift";
|
|
my $arguments = $gPreviousThriftPath." ".$newThriftFile;
|
|
my ($exitCode, $output) = callThriftAuditTool($arguments);
|
|
print $output if $gVerbose eq 1;
|
|
|
|
if($exitCode == 1)
|
|
{
|
|
# thrift_audit returns 1 when it is not able to find files or other non-audit failures
|
|
print "exiting with exit code =1 i = ".$i."\n";
|
|
print $output;
|
|
exit $exitCode;
|
|
}
|
|
if($exitCode != 2)
|
|
{
|
|
# thrift-audit return 2 for audit failures. So for Breaking changes we should get 2 as return value.
|
|
print $output;
|
|
die "\nTEST FAILURE: Breaking Change not detected for thrift file $newThriftFile, code=$exitCode \n";
|
|
}
|
|
if(index($output,getMessageSubString("break$i")) == -1)
|
|
{
|
|
#Audit tool detected failure, but not the expected one. The change in breaking thrift file does not match getMessageSubString()
|
|
print $output;
|
|
die "\nTest FAILURE: Audit tool detected failure, but not the expected one!\n";
|
|
}
|
|
else
|
|
{
|
|
#Thrift audit tool has detected audit failure and has returned exited to status code 2
|
|
print "Test Pass: Audit Failure detected for thrift file break$i.thrift \n";
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
sub auditNonBreakingChanges
|
|
{
|
|
my $breakingFileBaseName = $gThriftFileFolder."/warning";
|
|
my $newThriftFile;
|
|
$newThriftFile = $breakingFileBaseName.".thrift";
|
|
my $arguments = $gPreviousThriftPath." ".$newThriftFile;
|
|
my ($exitCode, $output) = callThriftAuditTool($arguments);
|
|
print $output if $gVerbose eq 1;
|
|
|
|
if($exitCode == 1)
|
|
{
|
|
# thrift_audit returns 1 when it is not able to find files or other non-audit failures
|
|
print "exiting with exit code = 1 for file warning.thrift\n";
|
|
exit $exitCode;
|
|
}
|
|
elsif($exitCode != 0)
|
|
{
|
|
# thrift-audit return 0 if there are no audit failures.
|
|
die "\nTEST FAILURE: Non Breaking changes returned failure for thrift file $newThriftFile \n";
|
|
}
|
|
else
|
|
{
|
|
#Thrift audit tool has exited with status 0.
|
|
print "Test Pass: Audit tool exits with success for warnings \n";
|
|
}
|
|
|
|
|
|
}
|
|
|
|
# -----------------------------------------------------------------------------------------------------
|
|
# call thriftAuditTool script
|
|
sub callThriftAuditTool ( $ )
|
|
{
|
|
my $args = shift;
|
|
|
|
my $command = "$gAuditToolPath --audit $args";
|
|
my $output = `$command 2>&1`;
|
|
my $exitCode = $? >> 8;
|
|
|
|
return ($exitCode,$output);
|
|
}
|
|
|
|
sub getMessageSubString( $ )
|
|
{
|
|
my $fileName = shift;
|
|
my %lookupTable = (
|
|
"break1" => "base_function3",
|
|
"break2" => "test_struct1",
|
|
"break3" => "test_struct1",
|
|
"break4" => "test_struct1",
|
|
"break5" => "test_struct1",
|
|
"break6" => "test_struct2",
|
|
"break7" => "test_struct6",
|
|
"break8" => "test_struct5",
|
|
"break9" => "test_struct1",
|
|
"break10" => "test_struct2",
|
|
"break11" => "test_struct3",
|
|
"break12" => "derived1_function1",
|
|
"break13" => "derived1_function6",
|
|
"break14" => "derived1_function4",
|
|
"break15" => "derived2_function1",
|
|
"break16" => "derived2_function5",
|
|
"break17" => "derived2_function6",
|
|
"break18" => "base_oneway",
|
|
"break19" => "base_function1",
|
|
"break20" => "test_enum1",
|
|
"break21" => "test_enum2",
|
|
"break22" => "test_enum1",
|
|
"break23" => "test_struct4",
|
|
"break24" => "derived1",
|
|
"break25" => "derived2",
|
|
"break26" => "base_function1",
|
|
"break27" => "base_function2_args",
|
|
"break28" => "derived1_function5_args",
|
|
"break29" => "base_function2_args",
|
|
"break30" => "derived1_function6",
|
|
"break31" => "base_function2_exception",
|
|
"break32" => "test_exception1",
|
|
"break33" => "derived1_function1_exception",
|
|
"break34" => "test_struct3",
|
|
);
|
|
if (not exists $lookupTable{ $fileName })
|
|
{
|
|
print "in the null case\n";
|
|
return "NULL";
|
|
}
|
|
|
|
my $retval = $lookupTable{ $fileName };
|
|
print "$fileName => $retval\n";
|
|
return $lookupTable{ $fileName };
|
|
}
|