diff options
Diffstat (limited to 'tools/lldb-perf/darwin')
-rw-r--r-- | tools/lldb-perf/darwin/formatters/fmts_tester.mm | 79 | ||||
-rw-r--r-- | tools/lldb-perf/darwin/formatters/formatters.cpp | 246 | ||||
-rw-r--r-- | tools/lldb-perf/darwin/sketch/foobar.sketch2 | bin | 0 -> 10027 bytes | |||
-rw-r--r-- | tools/lldb-perf/darwin/sketch/sketch.cpp | 380 |
4 files changed, 705 insertions, 0 deletions
diff --git a/tools/lldb-perf/darwin/formatters/fmts_tester.mm b/tools/lldb-perf/darwin/formatters/fmts_tester.mm new file mode 100644 index 0000000000000..57ce008297d9a --- /dev/null +++ b/tools/lldb-perf/darwin/formatters/fmts_tester.mm @@ -0,0 +1,79 @@ +//===-- fmts_tester.cpp -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +#import <Cocoa/Cocoa.h> +#include <vector> +#include <list> +#include <map> +#include <string> + +int main() +{ + NSArray* nsarray = @[@1,@2,@"hello world",@3,@4,@"foobar"]; + NSMutableArray* nsmutablearray = [[NSMutableArray alloc] initWithCapacity:5]; + [nsmutablearray addObject:@1]; + [nsmutablearray addObject:@2]; + [nsmutablearray addObject:@"hello world"]; + [nsmutablearray addObject:@3]; + [nsmutablearray addObject:@4]; + [nsmutablearray addObject:@"foobar"]; + NSDictionary* nsdictionary = @{@1 : @1, @2 : @2, @"hello" : @"world", @3 : @3}; + NSMutableDictionary* nsmutabledictionary = [[NSMutableDictionary alloc] initWithCapacity:5]; + [nsmutabledictionary setObject:@1 forKey:@1]; + [nsmutabledictionary setObject:@2 forKey:@2]; + [nsmutabledictionary setObject:@"hello" forKey:@"world"]; + [nsmutabledictionary setObject:@3 forKey:@3]; + NSString* str0 = @"Hello world"; + NSString* str1 = @"Hello ℥"; + NSString* str2 = @"Hello world"; + NSString* str3 = @"Hello ℥"; + NSString* str4 = @"Hello world"; + NSDate* me = [NSDate dateWithNaturalLanguageString:@"April 10, 1985"]; + NSDate* cutie = [NSDate dateWithNaturalLanguageString:@"January 29, 1983"]; + NSDate* mom = [NSDate dateWithNaturalLanguageString:@"May 24, 1959"]; + NSDate* dad = [NSDate dateWithNaturalLanguageString:@"October 29, 1954"]; + NSDate* today = [NSDate dateWithNaturalLanguageString:@"March 14, 2013"]; + NSArray* bundles = [NSBundle allBundles]; + NSArray* frameworks = [NSBundle allFrameworks]; + NSSet* nsset = [NSSet setWithArray:nsarray]; + NSMutableSet* nsmutableset = [NSMutableSet setWithCapacity:5]; + [nsmutableset addObject:@1]; + [nsmutableset addObject:@2]; + [nsmutableset addObject:@"hello world"]; + [nsmutableset addObject:@3]; + [nsmutableset addObject:@4]; + [nsmutableset addObject:@"foobar"]; + std::vector<int> vector; + vector.push_back(1); + vector.push_back(2); + vector.push_back(3); + vector.push_back(4); + vector.push_back(5); + std::list<int> list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + list.push_back(4); + list.push_back(5); + std::map<int,int> map; + map[1] = 1; + map[2] = 2; + map[3] = 3; + map[4] = 4; + map[5] = 5; + std::string sstr0("Hello world"); + std::string sstr1("Hello world"); + std::string sstr2("Hello world"); + std::string sstr3("Hello world"); + std::string sstr4("Hello world"); + int x = 0; + for (;;) + x++; +}
\ No newline at end of file diff --git a/tools/lldb-perf/darwin/formatters/formatters.cpp b/tools/lldb-perf/darwin/formatters/formatters.cpp new file mode 100644 index 0000000000000..ee38756184278 --- /dev/null +++ b/tools/lldb-perf/darwin/formatters/formatters.cpp @@ -0,0 +1,246 @@ +//===-- formatters.cpp ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <CoreFoundation/CoreFoundation.h> + +#include "lldb-perf/lib/Timer.h" +#include "lldb-perf/lib/Metric.h" +#include "lldb-perf/lib/Measurement.h" +#include "lldb-perf/lib/TestCase.h" +#include "lldb-perf/lib/Xcode.h" + +#include <iostream> +#include <unistd.h> +#include <fstream> + +using namespace lldb_perf; + +class FormattersTest : public TestCase +{ +public: + FormattersTest () : TestCase() + { + m_dump_std_vector_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "std-vector", "time to dump an std::vector"); + m_dump_std_list_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "std-list", "time to dump an std::list"); + m_dump_std_map_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "std-map", "time to dump an std::map"); + + // use this in manual mode + m_dump_std_string_measurement = CreateTimeMeasurement([] () -> void { + }, "std-string", "time to dump an std::string"); + + m_dump_nsstring_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,0,false); + }, "ns-string", "time to dump an NSString"); + + m_dump_nsarray_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "ns-array", "time to dump an NSArray"); + + m_dump_nsdictionary_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "ns-dictionary", "time to dump an NSDictionary"); + + m_dump_nsset_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "ns-set", "time to dump an NSSet"); + + m_dump_nsbundle_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "ns-bundle", "time to dump an NSBundle"); + + m_dump_nsdate_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,0,false); + }, "ns-date", "time to dump an NSDate"); + } + + virtual + ~FormattersTest () + { + } + + virtual bool + Setup (int& argc, const char**& argv) + { + m_app_path.assign(argv[1]); + m_out_path.assign(argv[2]); + m_target = m_debugger.CreateTarget(m_app_path.c_str()); + m_target.BreakpointCreateByName("main"); + SBLaunchInfo launch_info(argv); + return Launch (launch_info); + } + + void + DoTest () + { + SBFrame frame_zero(m_thread.GetFrameAtIndex(0)); + + m_dump_nsarray_measurement(frame_zero.FindVariable("nsarray", lldb::eDynamicCanRunTarget)); + m_dump_nsarray_measurement(frame_zero.FindVariable("nsmutablearray", lldb::eDynamicCanRunTarget)); + + m_dump_nsdictionary_measurement(frame_zero.FindVariable("nsdictionary", lldb::eDynamicCanRunTarget)); + m_dump_nsdictionary_measurement(frame_zero.FindVariable("nsmutabledictionary", lldb::eDynamicCanRunTarget)); + + m_dump_nsstring_measurement(frame_zero.FindVariable("str0", lldb::eDynamicCanRunTarget)); + m_dump_nsstring_measurement(frame_zero.FindVariable("str1", lldb::eDynamicCanRunTarget)); + m_dump_nsstring_measurement(frame_zero.FindVariable("str2", lldb::eDynamicCanRunTarget)); + m_dump_nsstring_measurement(frame_zero.FindVariable("str3", lldb::eDynamicCanRunTarget)); + m_dump_nsstring_measurement(frame_zero.FindVariable("str4", lldb::eDynamicCanRunTarget)); + + m_dump_nsdate_measurement(frame_zero.FindVariable("me", lldb::eDynamicCanRunTarget)); + m_dump_nsdate_measurement(frame_zero.FindVariable("cutie", lldb::eDynamicCanRunTarget)); + m_dump_nsdate_measurement(frame_zero.FindVariable("mom", lldb::eDynamicCanRunTarget)); + m_dump_nsdate_measurement(frame_zero.FindVariable("dad", lldb::eDynamicCanRunTarget)); + m_dump_nsdate_measurement(frame_zero.FindVariable("today", lldb::eDynamicCanRunTarget)); + + m_dump_nsbundle_measurement(frame_zero.FindVariable("bundles", lldb::eDynamicCanRunTarget)); + m_dump_nsbundle_measurement(frame_zero.FindVariable("frameworks", lldb::eDynamicCanRunTarget)); + + m_dump_nsset_measurement(frame_zero.FindVariable("nsset", lldb::eDynamicCanRunTarget)); + m_dump_nsset_measurement(frame_zero.FindVariable("nsmutableset", lldb::eDynamicCanRunTarget)); + + m_dump_std_vector_measurement(frame_zero.FindVariable("vector", lldb::eDynamicCanRunTarget)); + m_dump_std_list_measurement(frame_zero.FindVariable("list", lldb::eDynamicCanRunTarget)); + m_dump_std_map_measurement(frame_zero.FindVariable("map", lldb::eDynamicCanRunTarget)); + + auto sstr0 = frame_zero.FindVariable("sstr0", lldb::eDynamicCanRunTarget); + auto sstr1 = frame_zero.FindVariable("sstr1", lldb::eDynamicCanRunTarget); + auto sstr2 = frame_zero.FindVariable("sstr2", lldb::eDynamicCanRunTarget); + auto sstr3 = frame_zero.FindVariable("sstr3", lldb::eDynamicCanRunTarget); + auto sstr4 = frame_zero.FindVariable("sstr4", lldb::eDynamicCanRunTarget); + + m_dump_std_string_measurement.Start(); + Xcode::FetchVariable(sstr0,0,false); + m_dump_std_string_measurement.Stop(); + + m_dump_std_string_measurement.Start(); + Xcode::FetchVariable(sstr1,0,false); + m_dump_std_string_measurement.Stop(); + + m_dump_std_string_measurement.Start(); + Xcode::FetchVariable(sstr2,0,false); + m_dump_std_string_measurement.Stop(); + + m_dump_std_string_measurement.Start(); + Xcode::FetchVariable(sstr3,0,false); + m_dump_std_string_measurement.Stop(); + + m_dump_std_string_measurement.Start(); + Xcode::FetchVariable(sstr4,0,false); + m_dump_std_string_measurement.Stop(); + + } + + virtual void + TestStep (int counter, ActionWanted &next_action) + { + switch (counter) + { + case 0: + m_target.BreakpointCreateByLocation("fmts_tester.mm", 78); + next_action.Continue(); + break; + case 1: + DoTest (); + next_action.Continue(); + break; + case 2: + DoTest (); + next_action.Continue(); + break; + case 3: + DoTest (); + next_action.Continue(); + break; + case 4: + DoTest (); + next_action.Continue(); + break; + case 5: + DoTest (); + next_action.Continue(); + break; + case 6: + DoTest (); + next_action.Continue(); + break; + case 7: + DoTest (); + next_action.Continue(); + break; + case 8: + DoTest (); + next_action.Continue(); + break; + case 9: + DoTest (); + next_action.Continue(); + break; + case 10: + DoTest (); + next_action.Continue(); + break; + default: + next_action.Kill(); + break; + } + } + + virtual void + WriteResults (Results &results) + { + m_dump_std_vector_measurement.WriteAverageAndStandardDeviation(results); + m_dump_std_list_measurement.WriteAverageAndStandardDeviation(results); + m_dump_std_map_measurement.WriteAverageAndStandardDeviation(results); + m_dump_std_string_measurement.WriteAverageAndStandardDeviation(results); + + m_dump_nsstring_measurement.WriteAverageAndStandardDeviation(results); + m_dump_nsarray_measurement.WriteAverageAndStandardDeviation(results); + m_dump_nsdictionary_measurement.WriteAverageAndStandardDeviation(results); + m_dump_nsset_measurement.WriteAverageAndStandardDeviation(results); + m_dump_nsbundle_measurement.WriteAverageAndStandardDeviation(results); + m_dump_nsdate_measurement.WriteAverageAndStandardDeviation(results); + results.Write(m_out_path.c_str()); + } + +private: + // C++ formatters + TimeMeasurement<std::function<void(SBValue)>> m_dump_std_vector_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_std_list_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_std_map_measurement; + TimeMeasurement<std::function<void()>> m_dump_std_string_measurement; + + // Cocoa formatters + TimeMeasurement<std::function<void(SBValue)>> m_dump_nsstring_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_nsarray_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_nsdictionary_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_nsset_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_nsbundle_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_nsdate_measurement; + + // useful files + std::string m_app_path; + std::string m_out_path; +}; + +// argv[1] == path to app +// argv[2] == path to result +int main(int argc, const char * argv[]) +{ + FormattersTest frmtest; + frmtest.SetVerbose(true); + TestCase::Run(frmtest,argc,argv); + return 0; +} + diff --git a/tools/lldb-perf/darwin/sketch/foobar.sketch2 b/tools/lldb-perf/darwin/sketch/foobar.sketch2 Binary files differnew file mode 100644 index 0000000000000..553c698b180cd --- /dev/null +++ b/tools/lldb-perf/darwin/sketch/foobar.sketch2 diff --git a/tools/lldb-perf/darwin/sketch/sketch.cpp b/tools/lldb-perf/darwin/sketch/sketch.cpp new file mode 100644 index 0000000000000..93e39165c1333 --- /dev/null +++ b/tools/lldb-perf/darwin/sketch/sketch.cpp @@ -0,0 +1,380 @@ +//===-- sketch.cpp ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <CoreFoundation/CoreFoundation.h> + +#include "lldb-perf/lib/Timer.h" +#include "lldb-perf/lib/Metric.h" +#include "lldb-perf/lib/Measurement.h" +#include "lldb-perf/lib/TestCase.h" +#include "lldb-perf/lib/Xcode.h" + +#include <iostream> +#include <unistd.h> +#include <fstream> +#include <getopt.h> + +using namespace lldb_perf; + +static struct option g_long_options[] = { + { "verbose", no_argument, NULL, 'v' }, + { "sketch", required_argument, NULL, 'c' }, + { "foobar", required_argument, NULL, 'f' }, + { "out-file", required_argument, NULL, 'o' }, + { NULL, 0, NULL, 0 } +}; + +class SketchTest : public TestCase +{ +public: + SketchTest () : + m_fetch_frames_measurement ([this] () -> void + { + Xcode::FetchFrames (GetProcess(),false,false); + }, "fetch-frames", "time to dump backtrace for every frame in every thread"), + m_file_line_bp_measurement([this] (const char* file, uint32_t line) -> void + { + Xcode::CreateFileLineBreakpoint(GetTarget(), file, line); + }, "file-line-bkpt", "time to set a breakpoint given a file and line"), + m_fetch_modules_measurement ([this] () -> void + { + Xcode::FetchModules(GetTarget()); + }, "fetch-modules", "time to get info for all modules in the process"), + m_fetch_vars_measurement([this] (int depth) -> void + { + SBProcess process (GetProcess()); + auto threads_count = process.GetNumThreads(); + for (size_t thread_num = 0; thread_num < threads_count; thread_num++) + { + SBThread thread(process.GetThreadAtIndex(thread_num)); + SBFrame frame(thread.GetFrameAtIndex(0)); + Xcode::FetchVariables(frame,depth,GetVerbose()); + } + }, "fetch-vars", "time to dump variables for the topmost frame in every thread"), + m_run_expr_measurement([this] (SBFrame frame, const char* expr) -> void + { + SBValue value(frame.EvaluateExpression(expr, lldb::eDynamicCanRunTarget)); + Xcode::FetchVariable (value, 0, GetVerbose()); + }, "run-expr", "time to evaluate an expression and display the result") + { + m_app_path.clear(); + m_out_path.clear(); + m_doc_path.clear(); + m_print_help = false; + } + + virtual + ~SketchTest () + { + } + + virtual bool + ParseOption (int short_option, const char* optarg) + { + switch (short_option) + { + case 0: + return false; + + case -1: + return false; + + case '?': + case 'h': + m_print_help = true; + break; + + case 'v': + SetVerbose(true); + break; + + case 'c': + { + SBFileSpec file(optarg); + if (file.Exists()) + SetExecutablePath(optarg); + else + fprintf(stderr, "error: file specified in --sketch (-c) option doesn't exist: '%s'\n", optarg); + } + break; + + case 'f': + { + SBFileSpec file(optarg); + if (file.Exists()) + SetDocumentPath(optarg); + else + fprintf(stderr, "error: file specified in --foobar (-f) option doesn't exist: '%s'\n", optarg); + } + break; + + case 'o': + SetResultFilePath(optarg); + break; + + default: + m_print_help = true; + fprintf (stderr, "error: unrecognized option %c\n", short_option); + break; + } + return true; + } + + virtual struct option* + GetLongOptions () + { + return g_long_options; + } + + virtual bool + Setup (int& argc, const char**& argv) + { + TestCase::Setup(argc,argv); + bool error = false; + + if (GetExecutablePath() == NULL) + { + // --sketch is mandatory + error = true; + fprintf (stderr, "error: the '--sketch=PATH' option is mandatory\n"); + } + + if (GetDocumentPath() == NULL) + { + // --foobar is mandatory + error = true; + fprintf (stderr, "error: the '--foobar=PATH' option is mandatory\n"); + } + + if (error || GetPrintHelp()) + { + puts(R"( + NAME + lldb_perf_sketch -- a tool that measures LLDB peformance while debugging sketch. + + SYNOPSIS + lldb_perf_sketch --sketch=PATH --foobar=PATH [--out-file=PATH --verbose] + + DESCRIPTION + Runs a set of static timing and memory tasks against sketch and outputs results + to a plist file. + )"); + } + + if (error) + { + exit(1); + } + lldb::SBLaunchInfo launch_info = GetLaunchInfo(); + m_target = m_debugger.CreateTarget(m_app_path.c_str()); + m_file_line_bp_measurement("SKTDocument.m",245); + m_file_line_bp_measurement("SKTDocument.m",283); + m_file_line_bp_measurement("SKTText.m",326); + return Launch (launch_info); + } + + lldb::SBLaunchInfo + GetLaunchInfo () + { + const char* file_arg = m_doc_path.c_str(); + const char* persist_arg = "-ApplePersistenceIgnoreState"; + const char* persist_skip = "YES"; + const char* empty = nullptr; + const char* args[] = {file_arg,persist_arg,persist_skip,empty}; + return SBLaunchInfo(args); + } + + void + DoTest () + { + m_fetch_frames_measurement(); + m_fetch_modules_measurement(); + m_fetch_vars_measurement(1); + } + + virtual void + TestStep (int counter, ActionWanted &next_action) + { + static int launch = 1; + switch (counter % 10) + { + case 0: + { + DoTest (); + if (counter == 0) + m_file_line_bp_measurement("SKTDocument.m",254); + next_action.Continue(); + } + break; + + case 1: + { + DoTest (); + m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"properties"); + m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"[properties description]"); + m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"typeName"); + m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"data"); + m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"[data description]"); + next_action.Continue(); + } + break; + + case 2: + { + DoTest (); + next_action.Continue(); + } + break; + + case 3: + { + DoTest (); + next_action.StepOver(m_thread); + } + break; + + case 4: + { + DoTest (); + m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"layoutManager"); + m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"contents"); + next_action.StepOver(m_thread); + } + break; + + case 5: + { + DoTest (); + next_action.StepOver(m_thread); + } + break; + + case 6: + { + DoTest (); + next_action.StepOver(m_thread); + } + break; + + case 7: + { + DoTest (); + m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"@\"an NSString\""); + m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"[(id)@\"an NSString\" description]"); + m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"@[@1,@2,@3]"); + next_action.StepOut(m_thread); + } + break; + + case 8: + { + DoTest (); + m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"[graphics description]"); + m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"[selectionIndexes description]"); + m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"(BOOL)NSIntersectsRect(rect, graphicDrawingBounds)"); + } + next_action.CallNext(); + break; + case 9: + if (++launch < 10) + next_action.Relaunch(GetLaunchInfo()); + else + next_action.Kill(); + break; + + + default: + { + next_action.Kill(); + } + break; + } + } + + virtual void + WriteResults (Results &results) + { + m_fetch_frames_measurement.WriteAverageAndStandardDeviation(results); + m_file_line_bp_measurement.WriteAverageAndStandardDeviation(results); + m_fetch_modules_measurement.WriteAverageAndStandardDeviation(results); + m_fetch_vars_measurement.WriteAverageAndStandardDeviation(results); + m_run_expr_measurement.WriteAverageAndStandardDeviation(results); + results.Write(GetResultFilePath()); + } + + void + SetExecutablePath (const char* str) + { + if (str) + m_app_path.assign(str); + } + + const char* + GetExecutablePath () + { + if (m_app_path.empty()) + return NULL; + return m_app_path.c_str(); + } + + void + SetDocumentPath (const char* str) + { + if (str) + m_doc_path.assign(str); + } + + const char* + GetDocumentPath () + { + if (m_doc_path.empty()) + return NULL; + return m_doc_path.c_str(); + } + + + void + SetResultFilePath (const char* str) + { + if (str) + m_out_path.assign(str); + } + + const char* + GetResultFilePath () + { + if (m_out_path.empty()) + return "/dev/stdout"; + return m_out_path.c_str(); + } + + bool + GetPrintHelp () + { + return m_print_help; + } + +private: + Measurement<lldb_perf::TimeGauge, std::function<void()>> m_fetch_frames_measurement; + Measurement<lldb_perf::TimeGauge, std::function<void(const char*, uint32_t)>> m_file_line_bp_measurement; + Measurement<lldb_perf::TimeGauge, std::function<void()>> m_fetch_modules_measurement; + Measurement<lldb_perf::TimeGauge, std::function<void(int)>> m_fetch_vars_measurement; + Measurement<lldb_perf::TimeGauge, std::function<void(SBFrame, const char*)>> m_run_expr_measurement; + + std::string m_app_path; + std::string m_doc_path; + std::string m_out_path; + bool m_print_help; +}; + +int main(int argc, const char * argv[]) +{ + SketchTest test; + return TestCase::Run(test, argc, argv); +} |