草庐IT

go - 你能让这个 'incorrectly synchronized' 测试失败吗?

coder 2023-07-01 原文

  1. 此测试是否会在 x86、x64、ARM 上失败?
  2. 如果是这样,是否可以在不更改测试代码本身的情况下使其失败(在某种设置中)?

    func Test_WaitGroup_Simple(t *testing.T) {
        var condition bool
        var wg sync.WaitGroup
        wg.Add(1)
        go func() {
            condition = true
            wg.Done()
        }()
        wg.Wait()
        if !condition {
            t.Error("Condition is false. But expected was true.")
        }
    }
    

最佳答案

我已经改变了你的测试以在原子模块之间进行比较:

package main

import (
    "sync"
    // "sync/atomic"
    "fmt"
)

func main() {
    var condition int32
    var wg sync.WaitGroup
    wg.Add(1)
    go func() {
        condition = 101
        //atomic.StoreInt32(&condition,101)
        wg.Done()
    }()
    wg.Wait()
    if condition != 101 {
        fmt.Println("Condition is false. But expected was true.")
    } else {
        fmt.Println("Ok.")
    }
}

https://play.golang.org/p/8ewy2uMNNH

使用 go asm 我们可以检查将生成什么代码

go tool compile -S t.go

这里是内联代码的产生

atomic.StoreInt32(&condition,101)

    0x001d 00029 (t.go:15)  MOVL    $101, AX
    0x0022 00034 (t.go:15)  MOVQ    "".&condition+24(FP), CX
    0x0027 00039 (t.go:15)  XCHGL   AX, (CX)
    0x0029 00041 (t.go:16)  MOVQ    "".&wg+32(FP), AX
    0x002e 00046 (t.go:16)  MOVQ    AX, (SP)
    0x0032 00050 (t.go:16)  PCDATA  $0, $1

    0x0032 00050 (t.go:16)  CALL    sync.(*WaitGroup).Done(SB)

这里是生产

条件 = 101

0x001d 00029 (t.go:14)  MOVQ    "".&condition+24(FP), AX
0x0022 00034 (t.go:14)  MOVL    $101, (AX)
0x0028 00040 (t.go:16)  MOVQ    "".&wg+32(FP), AX
0x002d 00045 (t.go:16)  MOVQ    AX, (SP)
0x0031 00049 (t.go:16)  PCDATA  $0, $1

0x0031 00049 (t.go:16)  CALL    sync.(*WaitGroup).Done(SB)

如您所见,代码并没有太大区别。我使用 int32 只是为了使这两种情况都变得不同。 但是 go 为包括 bool 在内的其他原子类型生成或多或少相同的代码

如果您查看 i386 平台上 atomic/store 函数的实现,它实际上什么都不做:

sync/atomic/asm_amd64.s

TEXT ·StoreUint32(SB),NOSPLIT,$0-8
        MOVL    addr+0(FP), BP
        MOVL    val+4(FP), AX
        XCHGL   AX, 0(BP)
        RET

但是在32平台上存储64位已经很棘手了,当然不能用简单的“=”操作代替。

这就是为什么我的回答是:此测试将始终通过至少 386 和 amd64 平台。另一件事是这是一种不好的做法 - 但它实际上是另一张票的故事。

关于go - 你能让这个 'incorrectly synchronized' 测试失败吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45907588/

有关go - 你能让这个 'incorrectly synchronized' 测试失败吗?的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  3. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  4. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  5. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  6. ruby - Ruby 的 Hash 在比较键时使用哪种相等性测试? - 2

    我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。

  7. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  8. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  9. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  10. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

随机推荐