Skip to content

Commit

Permalink
Merge pull request #1482 from zigtools/techatrix/nix-test
Browse files Browse the repository at this point in the history
resolve config options in tests through the build system
  • Loading branch information
SuperAuguste authored Oct 1, 2023
2 parents bec9b61 + 59eff39 commit 08d68dc
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 78 deletions.
102 changes: 54 additions & 48 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,6 @@ pub fn build(b: *std.build.Builder) !void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});

const exe = b.addExecutable(.{
.name = "zls",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});

const exe_options = b.addOptions();
exe.addOptions("build_options", exe_options);

const single_threaded = b.option(bool, "single-threaded", "Build a single threaded Executable");
const pie = b.option(bool, "pie", "Build a Position Independent Executable");
const enable_tracy = b.option(bool, "enable_tracy", "Whether tracy should be enabled.") orelse false;
Expand All @@ -39,15 +29,6 @@ pub fn build(b: *std.build.Builder) !void {
const data_version_path = b.option([]const u8, "version_data_path", "Manually specify zig language reference file");
const override_version_data_file_path = b.option([]const u8, "version_data_file_path", "Relative path to version data file (if none, will be named with timestamp)");

exe_options.addOption(std.log.Level, "log_level", b.option(std.log.Level, "log_level", "The Log Level to be used.") orelse .info);
exe_options.addOption(bool, "enable_tracy", enable_tracy);
exe_options.addOption(bool, "enable_tracy_allocation", b.option(bool, "enable_tracy_allocation", "Enable using TracyAllocator to monitor allocations.") orelse enable_tracy);
exe_options.addOption(bool, "enable_tracy_callstack", b.option(bool, "enable_tracy_callstack", "Enable callstack graphs.") orelse enable_tracy);
exe_options.addOption(bool, "enable_failing_allocator", b.option(bool, "enable_failing_allocator", "Whether to use a randomly failing allocator.") orelse false);
exe_options.addOption(u32, "enable_failing_allocator_likelihood", b.option(u32, "enable_failing_allocator_likelihood", "The chance that an allocation will fail is `1/likelihood`") orelse 256);
exe_options.addOption(bool, "use_gpa", b.option(bool, "use_gpa", "Good for debugging") orelse (optimize == .Debug));
exe_options.addOption(bool, "coverage", coverage);

const version_string = v: {
const version_string = b.fmt("{d}.{d}.{d}", .{ zls_version.major, zls_version.minor, zls_version.patch });
const build_root_path = b.build_root.path orelse ".";
Expand Down Expand Up @@ -84,19 +65,52 @@ pub fn build(b: *std.build.Builder) !void {
},
}
};

const exe_options = b.addOptions();
exe_options.addOption(std.log.Level, "log_level", b.option(std.log.Level, "log_level", "The Log Level to be used.") orelse .info);
exe_options.addOption(bool, "enable_tracy", enable_tracy);
exe_options.addOption(bool, "enable_tracy_allocation", b.option(bool, "enable_tracy_allocation", "Enable using TracyAllocator to monitor allocations.") orelse enable_tracy);
exe_options.addOption(bool, "enable_tracy_callstack", b.option(bool, "enable_tracy_callstack", "Enable callstack graphs.") orelse enable_tracy);
exe_options.addOption(bool, "enable_failing_allocator", b.option(bool, "enable_failing_allocator", "Whether to use a randomly failing allocator.") orelse false);
exe_options.addOption(u32, "enable_failing_allocator_likelihood", b.option(u32, "enable_failing_allocator_likelihood", "The chance that an allocation will fail is `1/likelihood`") orelse 256);
exe_options.addOption(bool, "use_gpa", b.option(bool, "use_gpa", "Good for debugging") orelse (optimize == .Debug));
exe_options.addOption([]const u8, "version_string", version_string);
exe_options.addOption(std.SemanticVersion, "version", try std.SemanticVersion.parse(version_string));
exe_options.addOption([]const u8, "min_zig_string", min_zig_string);

const version = try std.SemanticVersion.parse(version_string);
exe_options.addOption(std.SemanticVersion, "version", version);
const build_options = b.addOptions();
const build_options_module = build_options.createModule();
build_options.addOption([]const u8, "version_string", version_string);
build_options.addOption(std.SemanticVersion, "version", try std.SemanticVersion.parse(version_string));

const known_folders_module = b.dependency("known_folders", .{}).module("known-folders");
exe.addModule("known-folders", known_folders_module);
const global_cache_path = try b.cache_root.join(b.allocator, &.{"zls"});
b.cache_root.handle.makePath(global_cache_path) catch |err| {
std.debug.panic("unable to make tmp path '{s}': {}", .{ global_cache_path, err });
};

const diffz_module = b.dependency("diffz", .{}).module("diffz");
exe.addModule("diffz", diffz_module);
const test_options = b.addOptions();
const test_options_module = test_options.createModule();
test_options.addOption([]const u8, "zig_exe_path", b.zig_exe);
test_options.addOption([]const u8, "global_cache_path", global_cache_path);

const exe_options_module = exe_options.createModule();
const known_folders_module = b.dependency("known_folders", .{}).module("known-folders");
const diffz_module = b.dependency("diffz", .{}).module("diffz");
const binned_allocator_module = b.dependency("binned_allocator", .{}).module("binned_allocator");

const exe = b.addExecutable(.{
.name = "zls",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
.single_threaded = single_threaded,
});
exe.pie = pie;
b.installArtifact(exe);

exe.addModule("build_options", exe_options_module);
exe.addModule("known-folders", known_folders_module);
exe.addModule("diffz", diffz_module);
exe.addModule("binned_allocator", binned_allocator_module);

if (enable_tracy) {
Expand All @@ -122,15 +136,10 @@ pub fn build(b: *std.build.Builder) !void {
}
}

exe.single_threaded = single_threaded;
exe.pie = pie;
b.installArtifact(exe);

const build_options_module = exe_options.createModule();

const gen_exe = b.addExecutable(.{
.name = "zls_gen",
.root_source_file = .{ .path = "src/config_gen/config_gen.zig" },
.single_threaded = true,
});

const gen_cmd = b.addRunArtifact(gen_exe);
Expand Down Expand Up @@ -169,44 +178,41 @@ pub fn build(b: *std.build.Builder) !void {
const version_data_module = b.addModule("version_data", .{ .source_file = version_data_path });
exe.addModule("version_data", version_data_module);

const test_step = b.step("test", "Run all the tests");
test_step.dependOn(b.getInstallStep());

var tests = b.addTest(.{
.root_source_file = .{ .path = "tests/tests.zig" },
.target = target,
.optimize = optimize,
.filter = test_filter,
});

const zls_module = b.addModule("zls", .{
.source_file = .{ .path = "src/zls.zig" },
.dependencies = &.{
.{ .name = "known-folders", .module = known_folders_module },
.{ .name = "diffz", .module = diffz_module },
.{ .name = "binned_allocator", .module = binned_allocator_module },
.{ .name = "build_options", .module = build_options_module },
.{ .name = "version_data", .module = version_data_module },
},
});

const test_step = b.step("test", "Run all the tests");
test_step.dependOn(b.getInstallStep());

var tests = b.addTest(.{
.root_source_file = .{ .path = "tests/tests.zig" },
.target = target,
.optimize = optimize,
.filter = test_filter,
.single_threaded = single_threaded,
});

tests.addModule("zls", zls_module);
tests.addModule("known-folders", known_folders_module);
tests.addModule("diffz", diffz_module);
tests.addModule("binned_allocator", binned_allocator_module);
tests.addModule("build_options", build_options_module);
tests.addModule("test_options", test_options_module);
test_step.dependOn(&b.addRunArtifact(tests).step);

var src_tests = b.addTest(.{
.root_source_file = .{ .path = "src/zls.zig" },
.target = target,
.optimize = optimize,
.filter = test_filter,
.single_threaded = single_threaded,
});
src_tests.addModule("known-folders", known_folders_module);
src_tests.addModule("diffz", diffz_module);
src_tests.addModule("binned_allocator", binned_allocator_module);
src_tests.addModule("build_options", build_options_module);
src_tests.addModule("test_options", test_options_module);
test_step.dependOn(&b.addRunArtifact(src_tests).step);

if (coverage) {
Expand Down
4 changes: 4 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,16 @@
nativeBuildInputs = [ zig ];
dontConfigure = true;
dontInstall = true;
doCheck = true;
langref = inputs.langref;
buildPhase = ''
mkdir -p .cache
ln -s ${pkgs.callPackage ./deps.nix { }} .cache/p
zig build install --cache-dir $(pwd)/zig-cache --global-cache-dir $(pwd)/.cache -Dversion_data_path=$langref -Dcpu=baseline -Doptimize=ReleaseSafe --prefix $out
'';
checkPhase = ''
zig build test --cache-dir $(pwd)/zig-cache --global-cache-dir $(pwd)/.cache -Dversion_data_path=$langref -Dcpu=baseline
'';
};
}
);
Expand Down
3 changes: 3 additions & 0 deletions src/DocumentStore.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,9 @@ pub fn resolveCImport(self: *DocumentStore, handle: Handle, node: Ast.Node.Index
defer tracy_zone.end();

if (!std.process.can_spawn) return null;
if (self.config.zig_exe_path == null) return null;
if (self.config.zig_lib_path == null) return null;
if (self.config.global_cache_path == null) return null;

self.lock.lock();
defer self.lock.unlock();
Expand Down
14 changes: 5 additions & 9 deletions src/Server.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1006,12 +1006,13 @@ fn validateConfiguration(server: *Server, config: *configuration.Configuration)

fn resolveConfiguration(server: *Server, config_arena: std.mem.Allocator, config: *configuration.Configuration) !void {
if (config.zig_exe_path == null) blk: {
comptime if (!std.process.can_spawn) break :blk;
std.debug.assert(!zig_builtin.is_test);
if (!std.process.can_spawn) break :blk;
config.zig_exe_path = try configuration.findZig(config_arena);
}

if (config.zig_exe_path) |exe_path| blk: {
comptime if (!std.process.can_spawn) break :blk;
if (!std.process.can_spawn) break :blk;
const env = configuration.getZigEnv(server.allocator, exe_path) orelse break :blk;
defer env.deinit();

Expand Down Expand Up @@ -1045,6 +1046,7 @@ fn resolveConfiguration(server: *Server, config_arena: std.mem.Allocator, config
}

if (config.global_cache_path == null) {
std.debug.assert(!zig_builtin.is_test);
const cache_dir_path = (try known_folders.getPath(server.allocator, .cache)) orelse {
log.warn("Known-folders could not fetch the cache path", .{});
return;
Expand Down Expand Up @@ -1086,7 +1088,7 @@ fn resolveConfiguration(server: *Server, config_arena: std.mem.Allocator, config
}

if (config.builtin_path == null) blk: {
comptime if (!std.process.can_spawn) break :blk;
if (!std.process.can_spawn) break :blk;
if (config.zig_exe_path == null) break :blk;
if (config.global_cache_path == null) break :blk;

Expand Down Expand Up @@ -1906,12 +1908,6 @@ pub fn waitAndWork(server: *Server) void {
server.wait_group.reset();
}

comptime {
if (build_options.coverage) {
std.testing.refAllDecls(@This());
}
}

pub fn loop(server: *Server) !void {
std.debug.assert(server.transport != null);
while (server.keepRunning()) {
Expand Down
6 changes: 3 additions & 3 deletions src/translate_c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,11 @@ pub fn translate(
};

const base_args = &[_][]const u8{
config.zig_exe_path orelse return null,
config.zig_exe_path.?,
"translate-c",
"--zig-lib-dir",
config.zig_lib_path orelse return null,
"--cache-dir",
config.zig_lib_path.?,
"--global-cache-dir",
config.global_cache_path.?,
"-lc",
"--listen=-",
Expand Down
22 changes: 8 additions & 14 deletions tests/context.zig
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
const std = @import("std");
const zls = @import("zls");
const builtin = @import("builtin");
const test_options = @import("test_options");

const Config = zls.Config;
const Server = zls.Server;
const types = zls.types;

/// initialize request taken from Visual Studio Code with the following changes:
/// - removed locale, rootPath, rootUri, trace, workspaceFolders
/// - removed capabilities.workspace.configuration
/// - removed capabilities.workspace.didChangeConfiguration
/// - removed capabilities.textDocument.publishDiagnostics
const initialize_msg =
\\{"processId":0,"clientInfo":{"name":"Visual Studio Code","version":"1.73.1"},"capabilities":{"workspace":{"applyEdit":true,"workspaceEdit":{"documentChanges":true,"resourceOperations":["create","rename","delete"],"failureHandling":"textOnlyTransactional","normalizesLineEndings":true,"changeAnnotationSupport":{"groupsOnLabel":true}},"didChangeWatchedFiles":{"dynamicRegistration":true,"relativePatternSupport":true},"symbol":{"dynamicRegistration":true,"symbolKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]},"tagSupport":{"valueSet":[1]},"resolveSupport":{"properties":["location.range"]}},"codeLens":{"refreshSupport":true},"executeCommand":{"dynamicRegistration":true},"workspaceFolders":true,"semanticTokens":{"refreshSupport":true},"fileOperations":{"dynamicRegistration":true,"didCreate":true,"didRename":true,"didDelete":true,"willCreate":true,"willRename":true,"willDelete":true},"inlineValue":{"refreshSupport":true},"inlayHint":{"refreshSupport":true},"diagnostics":{"refreshSupport":true}},"textDocument":{"synchronization":{"dynamicRegistration":true,"willSave":true,"willSaveWaitUntil":true,"didSave":true},"completion":{"dynamicRegistration":true,"contextSupport":true,"completionItem":{"snippetSupport":true,"commitCharactersSupport":true,"documentationFormat":["markdown","plaintext"],"deprecatedSupport":true,"preselectSupport":true,"tagSupport":{"valueSet":[1]},"insertReplaceSupport":true,"resolveSupport":{"properties":["documentation","detail","additionalTextEdits"]},"insertTextModeSupport":{"valueSet":[1,2]},"labelDetailsSupport":true},"insertTextMode":2,"completionItemKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]},"completionList":{"itemDefaults":["commitCharacters","editRange","insertTextFormat","insertTextMode"]}},"hover":{"dynamicRegistration":true,"contentFormat":["markdown","plaintext"]},"signatureHelp":{"dynamicRegistration":true,"signatureInformation":{"documentationFormat":["markdown","plaintext"],"parameterInformation":{"labelOffsetSupport":true},"activeParameterSupport":true},"contextSupport":true},"definition":{"dynamicRegistration":true,"linkSupport":true},"references":{"dynamicRegistration":true},"documentHighlight":{"dynamicRegistration":true},"documentSymbol":{"dynamicRegistration":true,"symbolKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]},"hierarchicalDocumentSymbolSupport":true,"tagSupport":{"valueSet":[1]},"labelSupport":true},"codeAction":{"dynamicRegistration":true,"isPreferredSupport":true,"disabledSupport":true,"dataSupport":true,"resolveSupport":{"properties":["edit"]},"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["","quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"]}},"honorsChangeAnnotations":false},"codeLens":{"dynamicRegistration":true},"formatting":{"dynamicRegistration":true},"rangeFormatting":{"dynamicRegistration":true},"onTypeFormatting":{"dynamicRegistration":true},"rename":{"dynamicRegistration":true,"prepareSupport":true,"prepareSupportDefaultBehavior":1,"honorsChangeAnnotations":true},"documentLink":{"dynamicRegistration":true,"tooltipSupport":true},"typeDefinition":{"dynamicRegistration":true,"linkSupport":true},"implementation":{"dynamicRegistration":true,"linkSupport":true},"colorProvider":{"dynamicRegistration":true},"foldingRange":{"dynamicRegistration":true,"rangeLimit":5000,"lineFoldingOnly":true,"foldingRangeKind":{"valueSet":["comment","imports","region"]},"foldingRange":{"collapsedText":false}},"declaration":{"dynamicRegistration":true,"linkSupport":true},"selectionRange":{"dynamicRegistration":true},"callHierarchy":{"dynamicRegistration":true},"semanticTokens":{"dynamicRegistration":true,"tokenTypes":["namespace","type","class","enum","interface","struct","typeParameter","parameter","variable","property","enumMember","event","function","method","macro","keyword","modifier","comment","string","number","regexp","operator","decorator"],"tokenModifiers":["declaration","definition","readonly","static","deprecated","abstract","async","modification","documentation","defaultLibrary"],"formats":["relative"],"requests":{"range":true,"full":{"delta":true}},"multilineTokenSupport":false,"overlappingTokenSupport":false,"serverCancelSupport":true,"augmentsSyntaxTokens":true},"linkedEditingRange":{"dynamicRegistration":true},"typeHierarchy":{"dynamicRegistration":true},"inlineValue":{"dynamicRegistration":true},"inlayHint":{"dynamicRegistration":true,"resolveSupport":{"properties":["tooltip","textEdits","label.tooltip","label.location","label.command"]}},"diagnostic":{"dynamicRegistration":true,"relatedDocumentSupport":false}},"window":{"showMessage":{"messageActionItem":{"additionalPropertiesSupport":true}},"showDocument":{"support":true},"workDoneProgress":true},"general":{"staleRequestSupport":{"cancel":true,"retryOnContentModified":["textDocument/semanticTokens/full","textDocument/semanticTokens/range","textDocument/semanticTokens/full/delta"]},"regularExpressions":{"engine":"ECMAScript","version":"ES2020"},"markdown":{"parser":"marked","version":"1.1.0"},"positionEncodings":["utf-16"]},"notebookDocument":{"synchronization":{"dynamicRegistration":true,"executionSummarySupport":true}}}}
;

const default_config: Config = .{
.enable_ast_check_diagnostics = false,
.semantic_tokens = .full,
.enable_inlay_hints = true,
.inlay_hints_exclude_single_argument = false,
.inlay_hints_show_builtin = true,

.zig_exe_path = test_options.zig_exe_path,
.zig_lib_path = null,
.global_cache_path = test_options.global_cache_path,
};

const allocator = std.testing.allocator;
Expand All @@ -44,15 +40,13 @@ pub const Context = struct {
_ = try context.server.sendRequestSync(context.arena.allocator(), "initialize", .{ .capabilities = .{} });
_ = try context.server.sendNotificationSync(context.arena.allocator(), "initialized", .{});

// TODO this line shouldn't be needed
context.server.client_capabilities.label_details_support = false;
context.server.client_capabilities.supports_textDocument_definition_linkSupport = true;

return context;
}

pub fn deinit(self: *Context) void {
_ = self.server.sendRequestSync(self.arena.allocator(), "shutdown", {}) catch {};
_ = self.server.sendRequestSync(self.arena.allocator(), "shutdown", {}) catch unreachable;
self.server.sendNotificationSync(self.arena.allocator(), "exit", {}) catch unreachable;
std.debug.assert(self.server.status == .exiting_success);
self.server.destroy();
self.arena.deinit();
}
Expand Down
4 changes: 0 additions & 4 deletions tests/language_features/cimport.zig
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,6 @@ fn testTranslate(c_source: []const u8) !translate_c.Result {
var ctx = try Context.init();
defer ctx.deinit();

if (ctx.server.config.global_cache_path == null or
ctx.server.config.zig_exe_path == null or
ctx.server.config.zig_lib_path == null) return error.SkipZigTest;

const result = (try translate_c.translate(allocator, ctx.server.config, &.{}, c_source)).?;

switch (result) {
Expand Down
Loading

0 comments on commit 08d68dc

Please sign in to comment.