Esempio n. 1
0
        private void AddParameter(DataRow dtRow, ref SqlParameterCollection parameters, ref StringBuilder sqlParamText, int counter, List <string> keyColumns)
        {
            string    columnName = dtRow["ColumnName"].ToString();
            SqlDbType colDBType  = (SqlDbType)Enum.Parse(typeof(SqlDbType), (string)dtRow["DataTypeName"], true);
            int       columnSize = Convert.ToInt32(dtRow["ColumnSize"]);

            if (counter != 0)   // the only use of counter is to help format sqlParamText
            {
                sqlParamText.Append(", ");
            }

            string paramName = NameCleaner.Clean("@" + columnName, string.Empty);

            parameters.Add(paramName, colDBType, columnSize, columnName);
            if (colDBType == SqlDbType.NVarChar || colDBType == SqlDbType.VarChar || colDBType == SqlDbType.Binary || colDBType == SqlDbType.VarBinary)
            {
                sqlParamText.AppendFormat("{0} {1}({2})", paramName, colDBType, (columnSize < 4000)? columnSize.ToString(): "max");
            }
            else
            {
                sqlParamText.AppendFormat("{0} {1}", paramName, colDBType);
            }

            // Allow default 'NULL' parameter if it's not the key column
            if (keyColumns != null && !keyColumns.Contains(columnName))
            {
                sqlParamText.Append(" = NULL");
            }
        }
Esempio n. 2
0
        private PropertyCtrlInfo BuildControlInfo(PropertyInfo pi, object parentObj)
        {
            PropertyCtrlInfo ci = new PropertyCtrlInfo();

            ci.PropertyInfo = pi;
            ci.ParentObject = parentObj;

            ci.Layout = AttributeInterrogator.GetAttribute <LayoutHint>(pi);
            if (ci.Layout == null)
            {
                ci.Layout = new LayoutHint();
            }

            if (_objHints.LabelHints != null && _objHints.LabelHints.ContainsKey(pi.Name))
            {
                ci.Layout.Label = _objHints.LabelHints[pi.Name];
            }
            if (string.IsNullOrEmpty(ci.Layout.Label))
            {
                ci.Layout.Label = NameCleaner.ToPhrase(pi.Name);
            }

            return(ci);
        }
Esempio n. 3
0
    public static void Run <TExports>(string pathBase, string json, Func <uint, bool>?skip)
        where TExports : class
    {
        TestInfo testInfo;

        using (var reader = new StreamReader(Path.Combine(pathBase, json)))
        {
            var settings = new JsonSerializerSettings();
            settings.Converters.Add(JsonSubtypesConverterBuilder
                                    .Of(typeof(Command), "type")
                                    .RegisterSubtype(typeof(ModuleCommand), CommandType.module)
                                    .RegisterSubtype(typeof(AssertReturn), CommandType.assert_return)
                                    .RegisterSubtype(typeof(AssertReturnCanonicalNan), CommandType.assert_return_canonical_nan)
                                    .RegisterSubtype(typeof(AssertReturnArithmeticNan), CommandType.assert_return_arithmetic_nan)
                                    .RegisterSubtype(typeof(AssertInvalid), CommandType.assert_invalid)
                                    .RegisterSubtype(typeof(AssertTrap), CommandType.assert_trap)
                                    .RegisterSubtype(typeof(AssertMalformed), CommandType.assert_malformed)
                                    .RegisterSubtype(typeof(AssertExhaustion), CommandType.assert_exhaustion)
                                    .RegisterSubtype(typeof(AssertUnlinkable), CommandType.assert_unlinkable)
                                    .RegisterSubtype(typeof(Register), CommandType.register)
                                    .RegisterSubtype(typeof(AssertReturn), CommandType.action)
                                    .RegisterSubtype(typeof(AssertUninstantiable), CommandType.assert_uninstantiable)
                                    .Build());
            settings.Converters.Add(JsonSubtypesConverterBuilder
                                    .Of(typeof(TestAction), "type")
                                    .RegisterSubtype(typeof(Invoke), TestActionType.invoke)
                                    .RegisterSubtype(typeof(Get), TestActionType.get)
                                    .Build());
            settings.Converters.Add(JsonSubtypesConverterBuilder
                                    .Of(typeof(TypedValue), "type")
                                    .RegisterSubtype(typeof(Int32Value), RawValueType.i32)
                                    .RegisterSubtype(typeof(Int64Value), RawValueType.i64)
                                    .RegisterSubtype(typeof(Float32Value), RawValueType.f32)
                                    .RegisterSubtype(typeof(Float64Value), RawValueType.f64)
                                    .Build());
            testInfo = (TestInfo)JsonSerializer.Create(settings).Deserialize(reader, typeof(TestInfo)) !;
        }

        ObjectMethods?methodsByName       = null;
        var           moduleMethodsByName = new Dictionary <string, ObjectMethods>();

        // From https://github.com/WebAssembly/spec/blob/master/interpreter/host/spectest.ml
        var imports = new ImportDictionary
        {
            { "spectest", "print_i32", new FunctionImport((Action <int>)(i => { })) },
            { "spectest", "print_i32_f32", new FunctionImport((Action <int, float>)((i, f) => { })) },
            { "spectest", "print_f64_f64", new FunctionImport((Action <double, double>)((d1, d2) => { })) },
            { "spectest", "print_f32", new FunctionImport((Action <float>)(i => { })) },
            { "spectest", "print_f64", new FunctionImport((Action <double>)(i => { })) },
            { "spectest", "global_i32", new GlobalImport(() => 666) },
            { "spectest", "global_i64", new GlobalImport(() => 666L) },
            { "spectest", "global_f32", new GlobalImport(() => 666.0F) },
            { "spectest", "global_f64", new GlobalImport(() => 666.0) },
            { "spectest", "table", new FunctionTable(10, 20) },                          // Table.alloc (TableType ({min = 10l; max = Some 20l}, FuncRefType))
            { "spectest", "memory", new MemoryImport(() => new UnmanagedMemory(1, 2)) }, // Memory.alloc (MemoryType {min = 1l; max = Some 2l})
        };

        var registrationCandidates = new ImportDictionary();

        Action     trapExpected;
        object?    result;
        object     obj;
        MethodInfo methodInfo;
        TExports?  exports = null;

        foreach (var command in testInfo.commands)
        {
            if (skip != null && skip(command.line))
            {
                continue;
            }

            void GetMethod(TestAction action, out MethodInfo info, out object host)
            {
                var methodSource = action.module == null ? methodsByName : moduleMethodsByName[action.module];

                Assert.IsNotNull(methodSource, $"{command.line} has no method source.");
                Assert.IsTrue(methodSource !.TryGetValue(NameCleaner.CleanName(action.field), out info !), $"{command.line} failed to look up method {action.field}");
                host = methodSource.Host;
            }

            try
            {
                switch (command)
                {
                case ModuleCommand module:
                    var path   = Path.Combine(pathBase, module.filename);
                    var parsed = Module.ReadFromBinary(path);     // Ensure the module parser can read it.
                    Assert.IsNotNull(parsed);
                    methodsByName = new ObjectMethods(exports = Compile.FromBinary <TExports>(path)(imports).Exports);
                    if (module.name != null)
                    {
                        moduleMethodsByName[module.name] = methodsByName;
                    }
                    continue;

                case AssertReturn assert:
                    GetMethod(assert.action, out methodInfo, out obj);
                    try
                    {
                        result = assert.action.Call(methodInfo, obj);
                    }
                    catch (TargetInvocationException x) when(x.InnerException != null)
                    {
                        throw new AssertFailedException($"{command.line}: {x.InnerException.Message}", x.InnerException);
                    }
                    catch (Exception x)
                    {
                        throw new AssertFailedException($"{command.line}: {x.Message}", x);
                    }
                    if (assert.expected?.Length > 0)
                    {
                        if (assert.expected[0].BoxedValue.Equals(result))
                        {
                            continue;
                        }

                        switch (assert.expected[0].type)
                        {
                        case RawValueType.f32:
                        {
                            var expected = ((Float32Value)assert.expected[0]).ActualValue;
                            Assert.AreEqual(expected, (float)result !, Math.Abs(expected * 0.000001f), $"{command.line}: f32 compare");
                        }
                            continue;

                        case RawValueType.f64:
                        {
                            var expected = ((Float64Value)assert.expected[0]).ActualValue;
                            Assert.AreEqual(expected, (double)result !, Math.Abs(expected * 0.000001), $"{command.line}: f64 compare");
                        }
                            continue;
                        }

                        throw new AssertFailedException($"{command.line}: Not equal: {assert.expected[0].BoxedValue} and {result}");
                    }
                    continue;

                case AssertReturnCanonicalNan assert:
                    GetMethod(assert.action, out methodInfo, out obj);
                    result = assert.action.Call(methodInfo, obj);
                    switch (assert.expected[0].type)
                    {
                    case RawValueType.f32:
                        Assert.IsTrue(float.IsNaN((float)result !), $"{command.line}: Expected NaN, got {result}");
                        continue;

                    case RawValueType.f64:
                        Assert.IsTrue(double.IsNaN((double)result !), $"{command.line}: Expected NaN, got {result}");
                        continue;

                    default:
                        throw new AssertFailedException($"{assert.expected[0].type} doesn't support NaN checks.");
                    }

                case AssertReturnArithmeticNan assert:
                    GetMethod(assert.action, out methodInfo, out obj);
                    result = assert.action.Call(methodInfo, obj);
                    switch (assert.expected[0].type)
                    {
                    case RawValueType.f32:
                        Assert.IsTrue(float.IsNaN((float)result !), $"{command.line}: Expected NaN, got {result}");
                        continue;

                    case RawValueType.f64:
                        Assert.IsTrue(double.IsNaN((double)result !), $"{command.line}: Expected NaN, got {result}");
                        continue;

                    default:
                        throw new AssertFailedException($"{assert.expected[0].type} doesn't support NaN checks.");
                    }

                case AssertInvalid assert:
                    trapExpected = () =>
                    {
                        try
                        {
                            Compile.FromBinary <TExports>(Path.Combine(pathBase, assert.filename));
                        }
                        catch (TargetInvocationException x) when(x.InnerException != null)
                        {
                            ExceptionDispatchInfo.Capture(x.InnerException).Throw();
                        }
                    };
                    switch (assert.text)
                    {
                    case "type mismatch":
                        try
                        {
                            trapExpected();
                        }
                        catch (StackTypeInvalidException)
                        {
                            continue;
                        }
                        catch (StackTooSmallException)
                        {
                            continue;
                        }
                        catch (ModuleLoadException)
                        {
                            continue;
                        }
                        catch (StackSizeIncorrectException)
                        {
                            continue;
                        }
                        catch (LabelTypeMismatchException)
                        {
                            continue;
                        }
                        catch (Exception x)
                        {
                            throw new AssertFailedException($"{command.line} threw an unexpected exception of type {x.GetType().Name}.");
                        }
                        throw new AssertFailedException($"{command.line} should have thrown an exception but did not.");

                    case "alignment must not be larger than natural":
                    case "global is immutable":
                        Assert.ThrowsException <CompilerException>(trapExpected, $"{command.line}");
                        continue;

                    case "unknown memory 0":
                    case "constant expression required":
                    case "duplicate export name":
                    case "unknown table":
                    case "unknown local":
                    case "multiple memories":
                    case "size minimum must not be greater than maximum":
                    case "memory size must be at most 65536 pages (4GiB)":
                    case "unknown label":
                    case "invalid result arity":
                    case "unknown type":
                        Assert.ThrowsException <ModuleLoadException>(trapExpected, $"{command.line}");
                        continue;

                    case "unknown global":
                    case "unknown memory":
                    case "unknown function":
                    case "unknown table 0":
                        try
                        {
                            trapExpected();
                        }
                        catch (CompilerException)
                        {
                            continue;
                        }
                        catch (ModuleLoadException)
                        {
                            continue;
                        }
                        catch (Exception x)
                        {
                            throw new AssertFailedException($"{command.line} threw an unexpected exception of type {x.GetType().Name}.");
                        }
                        throw new AssertFailedException($"{command.line} should have thrown an exception but did not.");

                    case "multiple tables":
                        Assert.ThrowsException <ModuleLoadException>(trapExpected, $"{command.line}");
                        continue;

                    default:
                        throw new AssertFailedException($"{command.line}: {assert.text} doesn't have a test procedure set up.");
                    }

                case AssertTrap assert:
                    trapExpected = () =>
                    {
                        GetMethod(assert.action, out methodInfo, out obj);
                        try
                        {
                            assert.action.Call(methodInfo, obj);
                        }
                        catch (TargetInvocationException x) when(x.InnerException != null)
                        {
                            ExceptionDispatchInfo.Capture(x.InnerException).Throw();
                        }
                    };

                    switch (assert.text)
                    {
                    case "integer divide by zero":
                        Assert.ThrowsException <DivideByZeroException>(trapExpected, $"{command.line}");
                        continue;

                    case "integer overflow":
                        Assert.ThrowsException <OverflowException>(trapExpected, $"{command.line}");
                        continue;

                    case "out of bounds memory access":
                        try
                        {
                            trapExpected();
                        }
                        catch (MemoryAccessOutOfRangeException)
                        {
                            continue;
                        }
                        catch (OverflowException)
                        {
                            continue;
                        }
                        catch (Exception x)
                        {
                            throw new AssertFailedException($"{command.line} threw an unexpected exception of type {x.GetType().Name}.");
                        }
                        throw new AssertFailedException($"{command.line} should have thrown an exception but did not.");

                    case "invalid conversion to integer":
                        Assert.ThrowsException <OverflowException>(trapExpected, $"{command.line}");
                        continue;

                    case "undefined element":
                    case "uninitialized element 7":
                        try
                        {
                            trapExpected();
                            throw new AssertFailedException($"{command.line}: Expected ModuleLoadException or IndexOutOfRangeException, but no exception was thrown.");
                        }
                        catch (ModuleLoadException)
                        {
                        }
                        catch (IndexOutOfRangeException)
                        {
                        }
                        catch (Exception x)
                        {
                            throw new AssertFailedException($"{command.line}: Expected ModuleLoadException or IndexOutOfRangeException, but received {x.GetType().Name}.");
                        }
                        continue;

                    case "indirect call type mismatch":
                        Assert.ThrowsException <InvalidCastException>(trapExpected, $"{command.line}");
                        continue;

                    case "unreachable":
                        Assert.ThrowsException <UnreachableException>(trapExpected, $"{command.line}");
                        continue;

                    case "uninitialized element":
                    case "uninitialized":
                        try
                        {
                            trapExpected();
                            throw new AssertFailedException($"{command.line}: Expected KeyNotFoundException or NullReferenceException, but no exception was thrown.");
                        }
                        catch (KeyNotFoundException)
                        {
                        }
                        catch (NullReferenceException)
                        {
                        }
                        catch (Exception x)
                        {
                            throw new AssertFailedException($"{command.line}: Expected KeyNotFoundException or NullReferenceException, but received {x.GetType().Name}.");
                        }
                        continue;

                    case "undefined":
                        try
                        {
                            trapExpected();
                            throw new AssertFailedException($"{command.line}: Expected KeyNotFoundException or IndexOutOfRangeException, but no exception was thrown.");
                        }
                        catch (KeyNotFoundException)
                        {
                        }
                        catch (IndexOutOfRangeException)
                        {
                        }
                        catch (Exception x)
                        {
                            throw new AssertFailedException($"{command.line}: Expected KeyNotFoundException or IndexOutOfRangeException, but received {x.GetType().Name}.");
                        }
                        continue;

                    case "indirect call":
                        Assert.ThrowsException <InvalidCastException>(trapExpected, $"{command.line}");
                        continue;

                    default:
                        throw new AssertFailedException($"{command.line}: {assert.text} doesn't have a test procedure set up.");
                    }

                case AssertMalformed assert:
                    continue;     // Not writing a WAT parser.

                case AssertExhaustion assert:
                    trapExpected = () =>
                    {
                        GetMethod(assert.action, out methodInfo, out obj);
                        try
                        {
                            assert.action.Call(methodInfo, obj);
                        }
                        catch (TargetInvocationException x) when(x.InnerException != null)
                        {
                            ExceptionDispatchInfo.Capture(x.InnerException).Throw();
                        }
                    };

                    switch (assert.text)
                    {
                    case "call stack exhausted":
                        Assert.ThrowsException <StackOverflowException>(trapExpected, $"{command.line}");
                        continue;

                    default:
                        throw new AssertFailedException($"{command.line}: {assert.text} doesn't have a test procedure set up.");
                    }

                case AssertUnlinkable assert:
                    trapExpected = () =>
                    {
                        try
                        {
                            Compile.FromBinary <TExports>(Path.Combine(pathBase, assert.filename))(imports);
                        }
                        catch (TargetInvocationException x) when(x.InnerException != null
#if DEBUG
                                                                 && !System.Diagnostics.Debugger.IsAttached
#endif
                                                                 )
                        {
                            ExceptionDispatchInfo.Capture(x.InnerException).Throw();
                        }
                    };
                    switch (assert.text)
                    {
                    case "data segment does not fit":
                    case "elements segment does not fit":
                        try
                        {
                            trapExpected();
                            throw new AssertFailedException($"{command.line}: Expected ModuleLoadException, MemoryAccessOutOfRangeException or OverflowException, but no exception was thrown.");
                        }
                        catch (Exception x) when(x is ModuleLoadException || x is MemoryAccessOutOfRangeException || x is OverflowException)
                        {
                        }
                        continue;

                    case "unknown import":
                    case "incompatible import type":
                        Assert.ThrowsException <ImportException>(trapExpected, $"{command.line}");
                        continue;

                    default:
                        throw new AssertFailedException($"{command.line}: {assert.text} doesn't have a test procedure set up.");
                    }

                case Register register:
                    Assert.IsNotNull(
                        moduleMethodsByName[register.@as] = register.name != null ? moduleMethodsByName[register.name] : methodsByName !,
                        $"{command.line} tried to register null as a module method source.");
                    Assert.IsNotNull(exports);
                    imports.AddFromExports(register.@as, exports !);
                    continue;

                case AssertUninstantiable assert:
                    trapExpected = () =>
                    {
                        try
                        {
                            Compile.FromBinary <TExports>(Path.Combine(pathBase, assert.filename));
                        }
                        catch (TargetInvocationException x) when(x.InnerException != null)
                        {
                            ExceptionDispatchInfo.Capture(x.InnerException).Throw();
                        }
                    };
                    switch (assert.text)
                    {
                    case "unreachable":
                        Assert.ThrowsException <ModuleLoadException>(trapExpected, $"{command.line}");
                        continue;

                    default:
                        throw new AssertFailedException($"{command.line}: {assert.text} doesn't have a test procedure set up.");
                    }

                default:
                    throw new AssertFailedException($"{command.line}: {command} doesn't have a test procedure set up.");
                }
            }
            catch (Exception x) when(!System.Diagnostics.Debugger.IsAttached && !(x is AssertFailedException))
            {
                throw new AssertFailedException($"{command.line}: {x}", x);
            }
        }

        if (skip != null)
        {
            Assert.Inconclusive("Some scenarios were skipped.");
        }
    }