예제 #1
0
        public Task <object> StartSession(string sessionId, MethodInfo testMethod, int schedulingSeed)
        {
#if DEBUG
            Console.WriteLine(">>    Session Id : {0}", sessionId);
            Console.WriteLine("============================================\n");
#endif

            // Initialize a new AsyncLocal session data
            this.testingApi.InitializeNewSession(sessionId);

            Console.WriteLine("\tSession {0}, Run {1}", this.testingApi.CurrentSession.Id, this.testingApi.CurrentSession.RunNumber);

            var testDefinition = GetTestDefinition(testMethod);

            // Create a main task so that we have control over
            // any exception thrown by arbitrary user code.
            //
            // The user code could be async or sync.
            // In either case, there could be multiple Tasks throwing exceptions.
            // This is challenging to deal with elegantly, so we simply silence exceptions
            // thrown by child Tasks, and only handle the exception thrown by the top-level Task.
            // See also: https://devblogs.microsoft.com/premier-developer/dissecting-the-async-methods-in-c/
            var mainTask = new Promise((resolve, reject) =>
            {
                /*Console.WriteLine("User Method\n  Is Async: {0}\n  Returns Task-like: {1}\n  Returns NekaraTask: {2}",
                 *  testDefinition.Kind.HasFlag(TestDefinition.MethodKind.IsAsync),
                 *  testDefinition.Kind.HasFlag(TestDefinition.MethodKind.ReturnsTaskLike),
                 *  testDefinition.Kind.HasFlag(TestDefinition.MethodKind.ReturnsNekaraTask));*/

                Nekara.Models.Task task;
                try
                {
                    if (testDefinition.Kind.HasFlag(TestDefinition.MethodKind.ReturnsNekaraTask))
                    {
                        task = (Nekara.Models.Task)testMethod.Invoke(null, null);
                    }

                    /*else if (testDefinition.Kind.HasFlag(TestDefinition.MethodKind.ReturnsTaskLike))
                     * {
                     *  task = Nekara.Models.Task.Run(() => testMethod.Invoke(null, null));
                     * }*/
                    else
                    {
                        task = Nekara.Models.Task.Run(() => testMethod.Invoke(null, null));
                    }

                    task.Wait();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("  [NekaraClient.StartSession] Main Task threw {0}!\n{1}", ex.GetType().Name, ex.Message);
                }

                try
                {
                    var record = this.testingApi.WaitForMainTask();
                    resolve(record);
                }
                catch (Exception ex)
                {
                    reject(ex);
                }
            }).Then(data =>
            {
                SessionRecord record = SessionRecord.Deserialize((string)data);

                // if result exists, this is a replayed session
                lock (this.records)
                {
                    if (!this.records.ContainsKey(sessionId))
                    {
                        this.records.Add(sessionId, record);
                    }
                    else
                    {
                        this.records[sessionId] = record;
                    }
                }
#if DEBUG
                Console.WriteLine("\n--------------------------------------------\n");
                Console.WriteLine("    Total Requests:\t{0}", this.testingApi.CurrentSession.numRequests);
                Console.WriteLine("    Average RTT:\t{0} ms", this.testingApi.CurrentSession.avgRtt);
                Console.WriteLine("\n\n==========[ Test {0} {1} ]==========\n", sessionId, record.reason == "" ? "PASSED" : "FAILED");
                if (record.reason != "")
                {
                    Console.WriteLine("  " + record.reason);
                    Console.WriteLine("\n==================================== END ===[ {0} ms ]===", record.elapsedMs);
                }
#endif

                return(record);
            }).Catch(ex =>
            {
                Console.WriteLine(ex);
                throw ex;
            });

            return(mainTask.Task);
        }