Commit eb3f807a authored by Ramin Halavati's avatar Ramin Halavati Committed by Commit Bot

Tests added to traffic annotation extractor clang tool.

Test suit is added to network traffic annotation extractor clang tool.

Bug: 656607
Bug: 690323
Change-Id: Ie7adc46694eba1bf1dc05bd08ccacf4c8e42743b
Reviewed-on: https://chromium-review.googlesource.com/590236
Commit-Queue: Ramin Halavati <rhalavati@chromium.org>
Reviewed-by: default avatarMartin Šrámek <msramek@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#491276}
parent 472df758
...@@ -208,11 +208,16 @@ that is to `return 1` from the `main()` function of the clang tool. ...@@ -208,11 +208,16 @@ that is to `return 1` from the `main()` function of the clang tool.
Synposis: Synposis:
```shell ```shell
tools/clang/scripts/test_tool.py <tool name> tools/clang/scripts/test_tool.py <tool name> [--apply-edits]
``` ```
The name of the tool binary and the subdirectory for the tool in The name of the tool binary and the subdirectory for the tool in
`//tools/clang` must match. The test runner finds all files that match the `//tools/clang` must match. The test runner finds all files that match the
pattern `//tools/clang/<tool name>/tests/*-original.cc`, runs the tool across pattern `//tools/clang/<tool name>/tests/*-original.cc`, and runs the tool
those files, and compared it to the `*-expected.cc` version. If there is a across those files.
mismatch, the result is saved in `*-actual.cc`. If `--apply-edits` switch is presented, tool outputs are applied to respective
files and compared to the `*-expected.cc` version. If there is a mismatch, the
result is saved in `*-actual.cc`.
When `--apply-edits` switch is not presented, tool outputs are compared to
`*-expected.txt` and if different, the result is saved in `*-actual.txt`. Note
that in this case, only one test file is expected.
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
"""Test harness for chromium clang tools.""" """Test harness for chromium clang tools."""
import argparse
import difflib import difflib
import glob import glob
import json import json
...@@ -42,10 +43,11 @@ def _NumberOfTestsToString(tests): ...@@ -42,10 +43,11 @@ def _NumberOfTestsToString(tests):
return '%d test%s' % (tests, 's' if tests != 1 else '') return '%d test%s' % (tests, 's' if tests != 1 else '')
def _RunToolAndApplyEdits(tools_clang_scripts_directory, def _ApplyTool(tools_clang_scripts_directory,
tool_to_test, tool_to_test,
test_directory_for_tool, test_directory_for_tool,
actual_files): actual_files,
apply_edits):
try: try:
# Stage the test files in the git index. If they aren't staged, then # Stage the test files in the git index. If they aren't staged, then
# run_tool.py will skip them when applying replacements. # run_tool.py will skip them when applying replacements.
...@@ -53,8 +55,11 @@ def _RunToolAndApplyEdits(tools_clang_scripts_directory, ...@@ -53,8 +55,11 @@ def _RunToolAndApplyEdits(tools_clang_scripts_directory,
args.extend(actual_files) args.extend(actual_files)
_RunGit(args) _RunGit(args)
# Launch the following pipeline: # Launch the following pipeline if |apply_edits| is True:
# run_tool.py ... | extract_edits.py | apply_edits.py ... # run_tool.py ... | extract_edits.py | apply_edits.py ...
# Otherwise just the first step is done and the result is written to
# actual_files[0].
processes = []
args = ['python', args = ['python',
os.path.join(tools_clang_scripts_directory, 'run_tool.py')] os.path.join(tools_clang_scripts_directory, 'run_tool.py')]
extra_run_tool_args_path = os.path.join(test_directory_for_tool, extra_run_tool_args_path = os.path.join(test_directory_for_tool,
...@@ -66,35 +71,40 @@ def _RunToolAndApplyEdits(tools_clang_scripts_directory, ...@@ -66,35 +71,40 @@ def _RunToolAndApplyEdits(tools_clang_scripts_directory,
args.extend(['--tool', tool_to_test, '-p', test_directory_for_tool]) args.extend(['--tool', tool_to_test, '-p', test_directory_for_tool])
args.extend(actual_files) args.extend(actual_files)
run_tool = subprocess.Popen(args, stdout=subprocess.PIPE) processes.append(subprocess.Popen(args, stdout=subprocess.PIPE))
args = [ if apply_edits:
'python', args = [
os.path.join(tools_clang_scripts_directory, 'extract_edits.py') 'python',
] os.path.join(tools_clang_scripts_directory, 'extract_edits.py')
extract_edits = subprocess.Popen( ]
args, stdin=run_tool.stdout, stdout=subprocess.PIPE) processes.append(subprocess.Popen(
args, stdin=processes[-1].stdout, stdout=subprocess.PIPE))
args = [
'python', args = [
os.path.join(tools_clang_scripts_directory, 'apply_edits.py'), '-p', 'python',
test_directory_for_tool os.path.join(tools_clang_scripts_directory, 'apply_edits.py'), '-p',
] test_directory_for_tool
apply_edits = subprocess.Popen( ]
args, stdin=extract_edits.stdout, stdout=subprocess.PIPE) processes.append(subprocess.Popen(
args, stdin=processes[-1].stdout, stdout=subprocess.PIPE))
# Wait for the pipeline to finish running + check exit codes. # Wait for the pipeline to finish running + check exit codes.
stdout, _ = apply_edits.communicate() stdout, _ = processes[-1].communicate()
for process in [run_tool, extract_edits, apply_edits]: for process in processes:
process.wait() process.wait()
if process.returncode != 0: if process.returncode != 0:
print "Failure while running the tool." print 'Failure while running the tool.'
return process.returncode return process.returncode
# Reformat the resulting edits via: git cl format. if apply_edits:
args = ['cl', 'format'] # Reformat the resulting edits via: git cl format.
args.extend(actual_files) args = ['cl', 'format']
_RunGit(args) args.extend(actual_files)
_RunGit(args)
else:
with open(actual_files[0], 'w') as output_file:
output_file.write(stdout)
return 0 return 0
...@@ -107,12 +117,17 @@ def _RunToolAndApplyEdits(tools_clang_scripts_directory, ...@@ -107,12 +117,17 @@ def _RunToolAndApplyEdits(tools_clang_scripts_directory,
def main(argv): def main(argv):
if len(argv) < 1: parser = argparse.ArgumentParser()
print 'Usage: test_tool.py <clang tool>' parser.add_argument(
print ' <clang tool> is the clang tool to be tested.' '--apply-edits',
sys.exit(1) action='store_true',
help='Applies the edits to the original test files and compares the '
tool_to_test = argv[0] 'reformatted new files with the expected files.')
parser.add_argument('tool_name',
nargs=1,
help='Clang tool to be tested.')
args = parser.parse_args(argv)
tool_to_test = args.tool_name[0]
print '\nTesting %s\n' % tool_to_test print '\nTesting %s\n' % tool_to_test
tools_clang_scripts_directory = os.path.dirname(os.path.realpath(__file__)) tools_clang_scripts_directory = os.path.dirname(os.path.realpath(__file__))
tools_clang_directory = os.path.dirname(tools_clang_scripts_directory) tools_clang_directory = os.path.dirname(tools_clang_scripts_directory)
...@@ -122,10 +137,15 @@ def main(argv): ...@@ -122,10 +137,15 @@ def main(argv):
'compile_commands.json') 'compile_commands.json')
source_files = glob.glob(os.path.join(test_directory_for_tool, source_files = glob.glob(os.path.join(test_directory_for_tool,
'*-original.cc')) '*-original.cc'))
ext = 'cc' if args.apply_edits else 'txt'
actual_files = ['-'.join([source_file.rsplit('-', 1)[0], 'actual.cc']) actual_files = ['-'.join([source_file.rsplit('-', 1)[0], 'actual.cc'])
for source_file in source_files] for source_file in source_files]
expected_files = ['-'.join([source_file.rsplit('-', 1)[0], 'expected.cc']) expected_files = ['-'.join([source_file.rsplit('-', 1)[0], 'expected.' + ext])
for source_file in source_files] for source_file in source_files]
if not args.apply_edits and len(actual_files) != 1:
print 'Only one test file is expected for testing without apply-edits.'
return 1
include_paths = [] include_paths = []
include_paths.append( include_paths.append(
os.path.realpath(os.path.join(tools_clang_directory, '../..'))) os.path.realpath(os.path.join(tools_clang_directory, '../..')))
...@@ -153,8 +173,9 @@ def main(argv): ...@@ -153,8 +173,9 @@ def main(argv):
# Run the tool. # Run the tool.
os.chdir(test_directory_for_tool) os.chdir(test_directory_for_tool)
exitcode = _RunToolAndApplyEdits(tools_clang_scripts_directory, tool_to_test, exitcode = _ApplyTool(tools_clang_scripts_directory, tool_to_test,
test_directory_for_tool, actual_files) test_directory_for_tool, actual_files,
args.apply_edits)
if (exitcode != 0): if (exitcode != 0):
return exitcode return exitcode
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include "net/traffic_annotation/network_traffic_annotation.h"
// This file provides all required dummy classes for:
// tools/clang/traffic_annotation_extractor/tests/test-original.cc
class GURL {};
namespace net {
class URLRequest {
public:
class Delegate;
};
class URLFetcherDelegate;
enum RequestPriority { TEST_VALUE };
class URLFetcher {
public:
enum RequestType { TEST_VALUE };
static std::unique_ptr<URLFetcher> Create(
const GURL& url,
URLFetcher::RequestType request_type,
URLFetcherDelegate* d);
static std::unique_ptr<URLFetcher> Create(
int id,
const GURL& url,
URLFetcher::RequestType request_type,
URLFetcherDelegate* d);
static std::unique_ptr<URLFetcher> Create(
const GURL& url,
URLFetcher::RequestType request_type,
URLFetcherDelegate* d,
NetworkTrafficAnnotationTag traffic_annotation);
static std::unique_ptr<URLFetcher> Create(
int id,
const GURL& url,
URLFetcher::RequestType request_type,
URLFetcherDelegate* d,
NetworkTrafficAnnotationTag traffic_annotation);
};
class URLRequestContext {
public:
std::unique_ptr<URLRequest> CreateRequest(
const GURL& url,
RequestPriority priority,
URLRequest::Delegate* delegate) const;
std::unique_ptr<URLRequest> CreateRequest(
const GURL& url,
RequestPriority priority,
URLRequest::Delegate* delegate,
NetworkTrafficAnnotationTag traffic_annotation) const;
};
} // namespace net
\ No newline at end of file
==== NEW ANNOTATION ====
/usr/local/google/home/rhalavati/workspace/chromium/src/tools/clang/traffic_annotation_extractor/tests/test-actual.cc
Global Namespace
14
Definition
id1
semantics {
sender: "sender1"
description: "desc1"
trigger: "trigger1"
data: "data1"
destination: GOOGLE_OWNED_SERVICE
}
policy {
cookies_allowed: NO
setting: "setting1"
chrome_policy {
SpellCheckServiceEnabled {
SpellCheckServiceEnabled: false
}
}
}
comments: "comment1"
==== ANNOTATION ENDS ====
==== NEW ANNOTATION ====
/usr/local/google/home/rhalavati/workspace/chromium/src/tools/clang/traffic_annotation_extractor/tests/test-actual.cc
Sample1
36
Partial
id2
completing_id2
semantics {
sender: "sender2"
description: "desc2"
trigger: "trigger2"
data: "data2"
destination: WEBSITE
}
==== ANNOTATION ENDS ====
==== NEW ANNOTATION ====
/usr/local/google/home/rhalavati/workspace/chromium/src/tools/clang/traffic_annotation_extractor/tests/test-actual.cc
Sample1
46
Completing
id3
policy {
cookies_allowed: YES
cookie_store: "user"
setting: "setting3"
chrome_policy {
SpellCheckServiceEnabled {
SpellCheckServiceEnabled: false
}
}
}
comments: "comment3"
==== ANNOTATION ENDS ====
==== NEW ANNOTATION ====
/usr/local/google/home/rhalavati/workspace/chromium/src/tools/clang/traffic_annotation_extractor/tests/test-actual.cc
Sample1
61
BranchedCompleting
id4
branch4
policy {
cookies_allowed: YES
cookie_store: "user"
setting: "setting4"
policy_exception_justification: "justification"
}
==== ANNOTATION ENDS ====
==== NEW ANNOTATION ====
/usr/local/google/home/rhalavati/workspace/chromium/src/tools/clang/traffic_annotation_extractor/tests/test-actual.cc
Sample2
83
Definition
undefined
Nothing here yet.
==== ANNOTATION ENDS ====
==== NEW CALL ====
/usr/local/google/home/rhalavati/workspace/chromium/src/tools/clang/traffic_annotation_extractor/tests/test-actual.cc
Sample2
73
net::URLFetcher::Create
0
==== CALL ENDS ====
==== NEW CALL ====
/usr/local/google/home/rhalavati/workspace/chromium/src/tools/clang/traffic_annotation_extractor/tests/test-actual.cc
Sample2
76
net::URLFetcher::Create
0
==== CALL ENDS ====
==== NEW CALL ====
/usr/local/google/home/rhalavati/workspace/chromium/src/tools/clang/traffic_annotation_extractor/tests/test-actual.cc
Sample2
79
net::URLFetcher::Create
1
==== CALL ENDS ====
==== NEW CALL ====
/usr/local/google/home/rhalavati/workspace/chromium/src/tools/clang/traffic_annotation_extractor/tests/test-actual.cc
Sample2
82
net::URLFetcher::Create
1
==== CALL ENDS ====
==== NEW CALL ====
/usr/local/google/home/rhalavati/workspace/chromium/src/tools/clang/traffic_annotation_extractor/tests/test-actual.cc
Sample3
90
net::URLRequestContext::CreateRequest
0
==== CALL ENDS ====
==== NEW CALL ====
/usr/local/google/home/rhalavati/workspace/chromium/src/tools/clang/traffic_annotation_extractor/tests/test-actual.cc
Sample3
91
net::URLRequestContext::CreateRequest
1
==== CALL ENDS ====
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "dummy_classes.h"
// This file provides samples for testing traffic_annotation_extractor clang
// tool.
namespace {
net::NetworkTrafficAnnotationTag kTrafficAnnotation =
net::DefineNetworkTrafficAnnotation("id1", R"(
semantics {
sender: "sender1"
description: "desc1"
trigger: "trigger1"
data: "data1"
destination: GOOGLE_OWNED_SERVICE
}
policy {
cookies_allowed: NO
setting: "setting1"
chrome_policy {
SpellCheckServiceEnabled {
SpellCheckServiceEnabled: false
}
}
}
comments: "comment1")");
}
void Sample1() {
net::PartialNetworkTrafficAnnotationTag partial_traffic_annotation =
net::DefinePartialNetworkTrafficAnnotation("id2", "completing_id2", R"(
semantics {
sender: "sender2"
description: "desc2"
trigger: "trigger2"
data: "data2"
destination: WEBSITE
})");
net::NetworkTrafficAnnotationTag completed_traffic_annotation =
net::CompleteNetworkTrafficAnnotation("id3", partial_traffic_annotation,
R"(
policy {
cookies_allowed: YES
cookie_store: "user"
setting: "setting3"
chrome_policy {
SpellCheckServiceEnabled {
SpellCheckServiceEnabled: false
}
}
}
comments: "comment3")");
net::NetworkTrafficAnnotationTag completed_branch_traffic_annotation =
net::BranchedCompleteNetworkTrafficAnnotation(
"id4", "branch4", partial_traffic_annotation, R"(
policy {
cookies_allowed: YES
cookie_store: "user"
setting: "setting4"
policy_exception_justification: "justification"
})");
}
void Sample2() {
net::URLFetcherDelegate* delegate = nullptr;
net::URLFetcher::Create(GURL(), net::URLFetcher::RequestType::TEST_VALUE,
delegate);
net::URLFetcher::Create(0, GURL(), net::URLFetcher::RequestType::TEST_VALUE,
delegate);
net::URLFetcher::Create(GURL(), net::URLFetcher::RequestType::TEST_VALUE,
delegate, kTrafficAnnotation);
net::URLFetcher::Create(0, GURL(), net::URLFetcher::RequestType::TEST_VALUE,
delegate, NO_TRAFFIC_ANNOTATION_YET);
}
void Sample3() {
net::URLRequest::Delegate* delegate = nullptr;
net::URLRequestContext context;
context.CreateRequest(GURL(), net::RequestPriority::TEST_VALUE, delegate);
context.CreateRequest(GURL(), net::RequestPriority::TEST_VALUE, delegate,
kTrafficAnnotation);
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment