Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add zoneinfo data for System.Runtime.TimeZoneInfoTests #38219

Merged
merged 13 commits into from
Jul 7, 2020
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion eng/liveBuilds.targets
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@
<LibrariesRuntimeFiles Condition="'$(TargetOS)' == 'Browser'"
Include="
$(LibrariesNativeArtifactsPath)dotnet.js;
$(LibrariesNativeArtifactsPath)dotnet.wasm;"
$(LibrariesNativeArtifactsPath)dotnet.wasm;
$(LibrariesNativeArtifactsPath)dotnet.timezones.blat;"
IsNative="true" />
</ItemGroup>

Expand Down
2 changes: 1 addition & 1 deletion eng/testing/tests.mobile.targets
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

<PropertyGroup Condition="'$(TargetOS)' == 'Browser'">
<!-- We need to set this in order to get extensibility on xunit category traits and other arguments we pass down to xunit via MSBuild properties -->
<RunScriptCommand>$HARNESS_RUNNER xharness wasm test --engine=$(JSEngine) --js-file=runtime.js -v --output-directory=$XHARNESS_OUT -- --run WasmTestRunner.dll $(AssemblyName).dll</RunScriptCommand>
<RunScriptCommand>$HARNESS_RUNNER xharness wasm test --engine=$(JSEngine) --js-file=runtime.js -v --output-directory=$XHARNESS_OUT -- --enable-zoneinfo --run WasmTestRunner.dll $(AssemblyName).dll</RunScriptCommand>
</PropertyGroup>

<!-- Generate a self-contained app bundle for Android with tests. -->
Expand Down
1 change: 1 addition & 0 deletions src/libraries/Native/native-binplace.proj
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<BinPlaceItem Include="$(NativeBinDir)*.dwarf" />
<BinPlaceItem Condition="'$(TargetOS)' == 'Browser'" Include="$(NativeBinDir)dotnet.js" />
<BinPlaceItem Condition="'$(TargetOS)' == 'Browser'" Include="$(NativeBinDir)dotnet.wasm" />
<BinPlaceItem Condition="'$(TargetOS)' == 'Browser'" Include="$(NativeBinDir)dotnet.timezones.blat" />
<FileWrites Include="@(BinPlaceItem)" />
</ItemGroup>

Expand Down
7 changes: 5 additions & 2 deletions src/mono/wasm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ MONO_BIN_DIR?=$(BINDIR)/mono/Browser.wasm.$(CONFIG)
SYS_NATIVE_DIR?=$(OBJDIR)/native/net5.0-Browser-$(CONFIG)-wasm/System.Native
BUILDS_BIN_DIR?=$(BINDIR)/native/net5.0-Browser-$(CONFIG)-wasm

all: build-native
all: build-native timezone-data

#
# EMSCRIPTEN SETUP
Expand Down Expand Up @@ -112,6 +112,9 @@ clean:
# Helper targets
.PHONY: runtime

timezone-data:
cp runtime/dotnet.timezones.blat $(BUILDS_BIN_DIR)
Comment on lines +115 to +116
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit in case you touch this again: this should ideally use the filename as the target name instead so make's dependency tracking works (right now it always copies the file even if it's already there:

$(BUILDS_BIN_DIR)/dotnet.timezones.blat: runtime/dotnet.timezones.blat
	cp runtime/dotnet.timezones.blat $@

(the $@ is a special variable that means the target filename: https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good to know. i can open another pr with this. thank you!


runtime:
EMSDK_PATH=$(TOP)/src/mono/wasm/emsdk $(TOP)/build.sh --subset mono --arch wasm --os Browser -c $(CONFIG)

Expand All @@ -129,4 +132,4 @@ run-tests-jsc-%:
PATH="$(JSVU):$(PATH)" $(DOTNET) build $(TOP)/src/libraries/$*/tests/ /t:Test /p:TargetOS=Browser /p:TargetArchitecture=wasm /p:Configuration=$(CONFIG) /p:JSEngine=JavaScriptCore

run-tests-%:
PATH="$(JSVU):$(PATH)" $(DOTNET) build $(TOP)/src/libraries/$*/tests/ /t:Test /p:TargetOS=Browser /p:TargetArchitecture=wasm /p:Configuration=$(CONFIG)
PATH="$(JSVU):$(PATH)" $(DOTNET) build $(TOP)/src/libraries/$*/tests/ /t:Test /p:TargetOS=Browser /p:TargetArchitecture=wasm /p:Configuration=$(CONFIG)
52 changes: 12 additions & 40 deletions src/mono/wasm/runtime-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,12 @@ function fail_exec (reason) {
}

function inspect_object (o) {
var r = "";
for(var p in o) {
var t = typeof o[p];
r += "'" + p + "' => '" + t + "', ";
}
return r;
var r = "";
for(var p in o) {
var t = typeof o[p];
r += "'" + p + "' => '" + t + "', ";
}
return r;
}

// Preprocess arguments
Expand Down Expand Up @@ -132,7 +132,7 @@ while (true) {
args = args.slice (1);
} else if (args [0] == "--enable-zoneinfo") {
enable_zoneinfo = true;
args = args.slice (1);
args = args.slice (1);
} else {
break;
}
Expand All @@ -149,7 +149,7 @@ function writeContentToFile(content, path)
if (typeof window == "undefined")
load ("mono-config.js");

var Module = {
var Module = {
mainScriptUrlOrBlob: "dotnet.js",

print: print,
Expand Down Expand Up @@ -205,37 +205,9 @@ var Module = {
Module.ccall ('mono_wasm_enable_on_demand_gc', 'void', ['number'], [0]);
}
if (enable_zoneinfo) {
// Load the zoneinfo data into the VFS rooted at /zoneinfo
FS.mkdir("zoneinfo");
Module['FS_createPath']('/', 'zoneinfo', true, true);
Module['FS_createPath']('/zoneinfo', 'Indian', true, true);
Module['FS_createPath']('/zoneinfo', 'Atlantic', true, true);
Module['FS_createPath']('/zoneinfo', 'US', true, true);
Module['FS_createPath']('/zoneinfo', 'Brazil', true, true);
Module['FS_createPath']('/zoneinfo', 'Pacific', true, true);
Module['FS_createPath']('/zoneinfo', 'Arctic', true, true);
Module['FS_createPath']('/zoneinfo', 'America', true, true);
Module['FS_createPath']('/zoneinfo/America', 'Indiana', true, true);
Module['FS_createPath']('/zoneinfo/America', 'Argentina', true, true);
Module['FS_createPath']('/zoneinfo/America', 'Kentucky', true, true);
Module['FS_createPath']('/zoneinfo/America', 'North_Dakota', true, true);
Module['FS_createPath']('/zoneinfo', 'Australia', true, true);
Module['FS_createPath']('/zoneinfo', 'Etc', true, true);
Module['FS_createPath']('/zoneinfo', 'Asia', true, true);
Module['FS_createPath']('/zoneinfo', 'Antarctica', true, true);
Module['FS_createPath']('/zoneinfo', 'Europe', true, true);
Module['FS_createPath']('/zoneinfo', 'Mexico', true, true);
Module['FS_createPath']('/zoneinfo', 'Africa', true, true);
Module['FS_createPath']('/zoneinfo', 'Chile', true, true);
Module['FS_createPath']('/zoneinfo', 'Canada', true, true);
var zoneInfoData = read ('zoneinfo.data', 'binary');
var metadata = JSON.parse(read ("mono-webassembly-zoneinfo-fs-smd.js.metadata", 'utf-8'));
var files = metadata.files;
for (var i = 0; i < files.length; ++i) {
var byteArray = zoneInfoData.subarray(files[i].start, files[i].end);
writeContentToFile(byteArray, files[i].filename);
}
MONO.wasm_load_timezone_data ("dotnet.timezones.blat");
}

MONO.mono_load_runtime_and_bcl (
config.vfs_prefix,
config.deploy_prefix,
Expand Down Expand Up @@ -282,7 +254,7 @@ if (typeof window == "undefined")
const IGNORE_PARAM_COUNT = -1;

var App = {
init: function () {
init: function () {

var assembly_load = Module.cwrap ('mono_wasm_assembly_load', 'number', ['string'])
var find_class = Module.cwrap ('mono_wasm_assembly_find_class', 'number', ['number', 'string', 'string'])
Expand Down Expand Up @@ -399,5 +371,5 @@ var App = {
} else {
fail_exec ("Unhanded argument: " + args [0]);
}
},
},
};
Binary file added src/mono/wasm/runtime/dotnet.timezones.blat
Binary file not shown.
60 changes: 59 additions & 1 deletion src/mono/wasm/runtime/library_mono.js
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,64 @@ var MonoSupportLib = {
// and nested class names like Foo/Bar to Foo.Bar
return className.replace(/\//g, '.').replace(/`\d+/g, '');
},

wasm_load_timezone_data: function (file_name) {
lewing marked this conversation as resolved.
Show resolved Hide resolved
var binary = read(file_name, "binary");
// The timezone file is generated by https://github.com/dotnet/blazor/tree/master/src/TimeZoneData.
// The file format of the TZ file look like so
//
// [4-byte magic number]
// [4 - byte length of manifest]
// [json manifest]
// [data bytes]
//
// The json manifest is an array that looks like so:
//
// [...["America/Fort_Nelson",2249],["America/Glace_Bay",2206]..]
//
// where the first token in each array is the relative path of the file on disk, and the second is the
// length of the file. The starting offset of a file can be calculated using the lengths of all files
// that appear prior to it.
var remainingData = new Uint8Array (binary);
var dataview = new DataView(remainingData.buffer);
var magic = dataview.getUint32(0, true);
// get magic number
if (magic != 0x626c6174) {
throw new Error ("File is of wrong type");
}
var manifestSize = dataview.getUint32(4, true);
var manifestContent = Module.UTF8ArrayToString(remainingData, 8, manifestSize);
var manifest = JSON.parse(manifestContent.split(/[a-zA-Z//_]+, [0-9]+/g));
lewing marked this conversation as resolved.
Show resolved Hide resolved
remainingData = remainingData.slice(manifestSize+8);

// Create the folder structure
// /usr/share/zoneinfo
// /usr/share/zoneinfo/Africa
// /usr/share/zoneinfo/Asia
// ..
FS.mkdir("usr");
Module['FS_createPath']('/', 'usr', true, true);
FS.mkdir("share");
Module['FS_createPath']('/usr', 'share', true, true);
FS.mkdir("/usr/share/zoneinfo");
lewing marked this conversation as resolved.
Show resolved Hide resolved
var folders = new Set()
manifest.filter(m => {
m = m[0].split('/')
if (m.length === 3) folders.add(m.slice(0,2).join('/'));
folders.add(m[0]);
});
folders.forEach(folder => {
Module['FS_createPath']('/usr/share/zoneinfo', folder, true, true);
});

for (row of manifest) {
var name = row[0];
var length = row[1];
var bytes = remainingData.slice(0, length);
Module['FS_createDataFile'](`/usr/share/zoneinfo/${name}`, null, bytes, true, true);
tqiu8 marked this conversation as resolved.
Show resolved Hide resolved
remainingData = remainingData.slice(length);
}
}
},

mono_wasm_add_typed_value: function (type, str_value, value) {
Expand Down Expand Up @@ -993,7 +1051,7 @@ var MonoSupportLib = {
mono_wasm_fire_bp: function () {
console.log ("mono_wasm_fire_bp");
debugger;
}
},
};

autoAddDeps(MonoSupportLib, '$MONO')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public override bool Execute ()
Directory.CreateDirectory(Path.Join(AppDir, "managed"));
foreach (var assembly in _assemblies!.Values)
File.Copy(assembly.Location, Path.Join(AppDir, "managed", Path.GetFileName(assembly.Location)), true);
foreach (var f in new string[] { "dotnet.wasm", "dotnet.js" })
foreach (var f in new string[] { "dotnet.wasm", "dotnet.js", "dotnet.timezones.blat" })
File.Copy(Path.Join (MicrosoftNetCoreAppRuntimePackDir, "native", f), Path.Join(AppDir, f), true);
File.Copy(MainJS!, Path.Join(AppDir, "runtime.js"), true);

Expand Down