public static async Task MainAsync(string[] args) { // Parse options and show helptext if insufficient g_Options = new Options(); Parser.Default.ParseArguments(args, g_Options); if (!g_Options.IsValid()) { var help = HelpText.AutoBuild(g_Options); Console.WriteLine(help.ToString()); return; } // Parse server URI if (String.IsNullOrEmpty(g_Options.Environment) || !g_Options.Environment.StartsWith("http")) { Console.WriteLine($"Invalid URI: {g_Options.Environment}"); return; } // Set up AvaTax g_Client = new AvaTaxClient("AvaTax-Connect", "1.0", Environment.MachineName, new Uri(g_Options.Environment)) .WithSecurity(g_Options.Username, g_Options.Password); // Attempt to connect PingResultModel ping = null; try { ping = g_Client.Ping(); } catch (Exception ex) { Console.WriteLine("Unable to contact AvaTax:"); HandleException(ex); return; } // Fetch the company FetchResult <CompanyModel> companies = null; try { companies = await g_Client.QueryCompaniesAsync(null, $"companyCode eq '{g_Options.CompanyCode}'", null, null, null); } catch (Exception ex) { Console.WriteLine("Exception fetching companies"); HandleException(ex); return; } // Check if the company exists if (companies == null || companies.count != 1) { Console.WriteLine($"Company with code '{g_Options.CompanyCode}' not found.\r\nPlease provide a valid companyCode using the '-c' parameter."); return; } // Check if the company is flagged as a test if ((companies.value[0].isTest != true) && IsPermanent(g_Options.DocType)) { Console.WriteLine($"Company with code '{g_Options.CompanyCode}' is not flagged as a test company.\r\nYour test is configured to use document type '{g_Options.DocType}'.\r\nThis is a permanent document type.\r\nWhen testing with permanent document types, AvaTax-Connect can only be run against a test company."); return; } // Did we authenticate? if (ping.authenticated != true) { Console.WriteLine("Authentication did not succeed. Please check your credentials and try again."); Console.WriteLine($" Username: {g_Options.Username}"); Console.WriteLine($" Password: REDACTED - PLEASE CHECK COMMAND LINE"); Console.WriteLine($" Environment: {g_Options.Environment}"); return; } // Print out information about our configuration Console.WriteLine($"AvaTax-Connect Performance Testing Tool"); Console.WriteLine($"======================================="); Console.WriteLine($" User: {g_Options.Username}"); Console.WriteLine($" Account: {ping.authenticatedAccountId}"); Console.WriteLine($" UserId: {ping.authenticatedUserId}"); Console.WriteLine($" CompanyCode: {g_Options.CompanyCode}"); Console.WriteLine($" SDK: {AvaTaxClient.API_VERSION}"); Console.WriteLine($" Environment: {g_Options.Environment}"); Console.WriteLine($" Tax Lines: {g_Options.Lines}"); Console.WriteLine($" Type: {g_Options.DocType}"); Console.WriteLine($" Threads: {g_Options.Threads}"); Console.WriteLine(); Console.WriteLine(" Call Server DB Svc Net Client Total"); // Use transaction builder var tb = new TransactionBuilder(g_Client, g_Options.CompanyCode, g_Options.DocType, "ABC"); // Add lines for (int i = 0; i < g_Options.Lines; i++) { tb.WithLine(100.0m) .WithLineAddress(TransactionAddressType.PointOfOrderAcceptance, "123 Main Street", null, null, "Irvine", "CA", "92615", "US") .WithLineAddress(TransactionAddressType.PointOfOrderOrigin, "123 Main Street", null, null, "Irvine", "CA", "92615", "US") .WithLineAddress(TransactionAddressType.ShipFrom, "123 Main Street", null, null, "Irvine", "CA", "92615", "US") .WithLineAddress(TransactionAddressType.ShipTo, "123 Main Street", null, null, "Irvine", "CA", "92615", "US"); } g_Model = tb.GetCreateTransactionModel(); // Discard the first call? try { if (g_Options.DiscardFirstCall.HasValue && g_Options.DiscardFirstCall.Value) { var t = g_Client.CreateTransaction(null, g_Model); } } catch (Exception ex) { Console.WriteLine("Cannot connect to AvaTax."); HandleException(ex); return; } // Connect to AvaTax and print debug information g_TotalDuration = new CallDuration(); g_TotalMs = 0; List <Task> threads = new List <Task>(); for (int i = 0; i < g_Options.Threads; i++) { var task = Task.Run(ConnectThread); threads.Add(task); } await Task.WhenAll(threads); // Compute some averages double avg = g_TotalMs * 1.0 / g_Count; double total_overhead = (g_TotalDuration.SetupDuration.TotalMilliseconds + g_TotalDuration.ParseDuration.TotalMilliseconds); double total_transit = g_TotalDuration.TransitDuration.TotalMilliseconds; double total_server = g_TotalDuration.ServerDuration.TotalMilliseconds; double avg_overhead = total_overhead / g_Count; double avg_transit = total_transit / g_Count; double avg_server = total_server / g_Count; double pct_overhead = total_overhead / g_TotalMs; double pct_transit = total_transit / g_TotalMs; double pct_server = total_server / g_TotalMs; // Print out the totals Console.WriteLine(); Console.WriteLine($"Finished {g_Count} calls in {g_TotalMs} milliseconds."); Console.WriteLine($" Average: {avg.ToString("0.00")}ms; {avg_overhead.ToString("0.00")}ms overhead, {avg_transit.ToString("0.00")}ms transit, {avg_server.ToString("0.00")}ms server."); Console.WriteLine($" Percentage: {pct_overhead.ToString("P")} overhead, {pct_transit.ToString("P")} transit, {pct_server.ToString("P")} server."); Console.WriteLine($" Total: {total_overhead} overhead, {total_transit} transit, {total_server} server."); }