From patchwork Tue Jul 9 23:05:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josh Steadmon X-Patchwork-Id: 11037571 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E069F138B for ; Tue, 9 Jul 2019 23:05:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D281928762 for ; Tue, 9 Jul 2019 23:05:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C6C6A2890F; Tue, 9 Jul 2019 23:05:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E2DE328762 for ; Tue, 9 Jul 2019 23:05:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727001AbfGIXFz (ORCPT ); Tue, 9 Jul 2019 19:05:55 -0400 Received: from mail-pf1-f202.google.com ([209.85.210.202]:43951 "EHLO mail-pf1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726133AbfGIXFz (ORCPT ); Tue, 9 Jul 2019 19:05:55 -0400 Received: by mail-pf1-f202.google.com with SMTP id 6so135494pfz.10 for ; Tue, 09 Jul 2019 16:05:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to; bh=wTyculBfBH7rjA+cBKMgZTM7i5F2ir8ueapSceISMVI=; b=gqeU8/s23FXx/fZLp76zkTyvL7yiwSAOFai6D1HWrHmnUASVrmBvdfKhjvA+6jIV0O Mz89S860QyUZLRTXAsTv8JpNFNyLuc8N4T1gtH0cXLOYCZ3lrKuYb5Qn24qR9Lsf71AE MEzbty+0yhvJv3in84mSz/llWLaFNjNz7/fgd/sjC74laaCogNOeZbZ8oHGOV4N9bSSO q7sylXBJiA3N8zedZo/yJ3UwOgdKBVqF6h3LcIxf2JJaOfaOgDKea30ay1XcAZbZhXTG aY3Fv4GzXCxeK7ZR57aaixQmqlQsmhlXjzwi+XcnbRMgRVg+UXgauOH+cphYcLQLs6mz q6EQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to; bh=wTyculBfBH7rjA+cBKMgZTM7i5F2ir8ueapSceISMVI=; b=Qm0/G+60rS+pC37he9srg/rt9AJVxxQZQ8fJvwtdZrMqk+x49FFR3U/Vk1M3YkZgYN WuEB1yaf5zfpps+UXxWaZXVjJ2skMggMOyiJgTYT2DC2Z4jrsmY9/u97GMpIPyD6eUns s4Lcn3S7GRLkEFJMtWnLABlZrzvvWERb4WfppPLIqU+hl525a9d3l7jOIGvjYAADBRgm BWu1mJWg+EnV0DU7yNmOEZVdGoj6UWZp77pCtRW4h8AQMY3OuPZC2a/aB+NgmCrukz3w 5wSeX/M7fMVQmWpSWTKkOS07/KPqyjy19pDvERse6eVg9GJfLlRJhIm/SGjQUjtfEubZ UZ+A== X-Gm-Message-State: APjAAAVSybcxWRAnLAd0RCraZeISS5HHkzRXegCb4Yr50MA9RpboWtSz KWCiivLCWB1JEcxCeZ51m+cCcVyjdKkj/q9OZ97piPqGPZTAkwLC1qMeY4h2tlyk84JJN75mBNM tuOd55nt0esasty7FiG/SnFWOW0MHCMZoAB/1wJ8apCajlXivkr1nlevbwERYUAU= X-Google-Smtp-Source: APXvYqyJfy3ZGc/ERC9ULHcYjhzpVnVZCr+1aNH0eCia1VvmNCDBdjJz69GB8VCi7T/2wAnCLavPJaHTeEvUKw== X-Received: by 2002:a65:640d:: with SMTP id a13mr33200469pgv.256.1562713554197; Tue, 09 Jul 2019 16:05:54 -0700 (PDT) Date: Tue, 9 Jul 2019 16:05:44 -0700 In-Reply-To: Message-Id: <3fa4e9eef84ba00c631c82fb3a2eacb8439df9e5.1562712943.git.steadmon@google.com> Mime-Version: 1.0 References: X-Mailer: git-send-email 2.22.0.510.g264f2c817a-goog Subject: [RFC PATCH v2 2/3] trace2: add a schema validator for trace2 events From: Josh Steadmon To: git@vger.kernel.org, gitster@pobox.com, git@jeffhostetler.com, avarab@gmail.com, peff@peff.net, jnareb@gmail.com Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP trace_schema_validator can be used to verify that trace2 event output conforms to the expectations set by the API documentation and codified in event_schema.json (or strict_schema.json). This allows us to build a regression test to verify that trace2 output does not change unexpectedly. Signed-off-by: Josh Steadmon --- t/trace_schema_validator/.gitignore | 1 + t/trace_schema_validator/Makefile | 10 +++ .../trace_schema_validator.go | 78 +++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 t/trace_schema_validator/.gitignore create mode 100644 t/trace_schema_validator/Makefile create mode 100644 t/trace_schema_validator/trace_schema_validator.go diff --git a/t/trace_schema_validator/.gitignore b/t/trace_schema_validator/.gitignore new file mode 100644 index 0000000000..c3f1e04e9e --- /dev/null +++ b/t/trace_schema_validator/.gitignore @@ -0,0 +1 @@ +trace_schema_validator diff --git a/t/trace_schema_validator/Makefile b/t/trace_schema_validator/Makefile new file mode 100644 index 0000000000..ed22675e5d --- /dev/null +++ b/t/trace_schema_validator/Makefile @@ -0,0 +1,10 @@ +.PHONY: fetch_deps clean + +trace_schema_validator: fetch_deps trace_schema_validator.go + go build + +fetch_deps: + go get github.com/xeipuuv/gojsonschema + +clean: + rm -f trace_schema_validator diff --git a/t/trace_schema_validator/trace_schema_validator.go b/t/trace_schema_validator/trace_schema_validator.go new file mode 100644 index 0000000000..f779ac5ff5 --- /dev/null +++ b/t/trace_schema_validator/trace_schema_validator.go @@ -0,0 +1,78 @@ +// trace_schema_validator validates individual lines of an input file against a +// provided JSON-Schema for git trace2 event output. +// +// Traces can be collected by setting the GIT_TRACE2_EVENT environment variable +// to an absolute path and running any Git command; traces will be appended to +// the file. +// +// Traces can then be verified like so: +// trace_schema_validator \ +// --trace2_event_file /path/to/trace/output \ +// --schema_file /path/to/schema +package main + +import ( + "bufio" + "flag" + "log" + "os" + "path/filepath" + + "github.com/xeipuuv/gojsonschema" +) + +// Required flags +var schemaFile = flag.String("schema_file", "", "JSON-Schema filename") +var trace2EventFile = flag.String("trace2_event_file", "", "trace2 event filename") + +func main() { + flag.Parse() + if *schemaFile == "" || *trace2EventFile == "" { + log.Fatal("Both --schema_file and --trace2_event_file are required.") + } + schemaURI, err := filepath.Abs(*schemaFile) + if err != nil { + log.Fatal("Can't get absolute path for schema file: ", err) + } + schemaURI = "file://" + schemaURI + + schemaLoader := gojsonschema.NewReferenceLoader(schemaURI) + schema, err := gojsonschema.NewSchema(schemaLoader) + if err != nil { + log.Fatal("Problem loading schema: ", err) + } + + tracesFile, err := os.Open(*trace2EventFile) + if err != nil { + log.Fatal("Problem opening trace file: ", err) + } + defer tracesFile.Close() + + scanner := bufio.NewScanner(tracesFile) + + count := 0 + for ; scanner.Scan(); count++ { + if count%10000 == 0 { + // Travis-CI expects regular output or it will time out. + log.Print("Validated items: ", count) + } + event := gojsonschema.NewStringLoader(scanner.Text()) + result, err := schema.Validate(event) + if err != nil { + log.Fatal(err) + } + if !result.Valid() { + log.Print("Trace event is invalid: ", scanner.Text()) + for _, desc := range result.Errors() { + log.Print("- ", desc) + } + os.Exit(1) + } + } + + if err := scanner.Err(); err != nil { + log.Fatal("Scanning error: ", err) + } + + log.Print("Validated events: ", count) +}