测试程序流生成 在测试接口的后续初始化中丢失主流文件中的选项



>我通过主流文件中的选项哈希传入一些参数:

Flow.create(environment: :ws, interface: 'MyTestLibrary::Interface', lib_version: Origen.top_level.lib_version) do
import "components/bist"
import "components/func"
pass 1, softbin: 55
end

问题是,当调用其他子流时,这些选项不会保持不变。 以下是调用测试接口的第一个时间的撬动会话:

14: def initialize(options = {})
15:   options = {
16:     lib_version: nil
18:   }.merge!(options)
=> 19:   binding.pry
[1] pry(#<MyTestLibrary::Interface>)> options
=> {:lib_version=>"3.14", :environment=>:ws, :interface=>"MyTestLibrary::Interface"}

但是,这是第二次命中同一断点时的撬动会话:

[1] pry(#<MyTestLibrary::Interface>)> options
=> {:lib_version=>nil}

我想我有几个问题:

  1. 主流选项不是应该持久化吗 子流,没有对用户进行任何额外工作?
  2. 为什么要重新初始化接口? 似乎每代命令应该只发生一次。

提前感谢

  • 编辑*

@Ginty,您在回答中说了以下内容:

就传递到顶级流中的选项而言,实际上没有任何保证将它们传递到初始化中。相反,接口应该创建启动和关闭方法,如果它想要拦截它们:

但是在文档中,我看到以下内容:

要使接口运行,它必须实现流将调用的所有方法。通常还创建一个初始化方法,该方法将捕获传入 Flow.create 的任何选项(例如在我们的流示例中将环境声明为探测器)。

此外,启动方法看起来像在初始化接口后运行的回调。 在接口完成初始化之前,我需要使用选项哈希传递的信息。 这不是在创建下游用户不需要担心的脆弱运行顺序依赖项吗? 问候

假设我们有两个顶级流和一个流组件:

# program/prb1.rb
Flow.create interface: 'MyApp::Interface', temperature: 25 do
import 'components/ram'
end
# program/prb2.rb
Flow.create interface: 'MyApp::Interface', temperature: 125 do
import 'components/ram'
end
# program/components/_ram.rb
Flow.create do |options|
end

而这个界面:

module MyApp
class Interface
include OrigenTesters::ProgramGenerators
def initialize(options = {})
puts "New interface!"
puts "The temperature is: #{options[:temperature]}"
super
end
end
end

然后,如果我们通过在程序目录上运行 prog gen 来生成两个流,origen p program,那么我们会看到接口被实例化两次,每个顶级流一次:

$ origen p program
[INFO]       0.006[0.006]    || **********************************************************************
[INFO]       0.010[0.004]    || Generating... prb1.rb
New interface!
The temperature is: 25
[INFO]       0.024[0.014]    || Generating... prb2.rb
New interface!
The temperature is: 125
[INFO]       0.052[0.028]    || Writing... prb1.tf
[INFO]       0.053[0.001]    || *** NEW FILE *** To save it:  cp output/testflow/mfh.testflow.group/prb1.tf .ref/prb1.tf
[INFO]       0.054[0.000]    || **********************************************************************
[INFO]       0.058[0.004]    || Writing... prb2.tf
[INFO]       0.059[0.001]    || *** NEW FILE *** To save it:  cp output/testflow/mfh.testflow.group/prb2.tf .ref/prb2.tf
[INFO]       0.059[0.000]    || **********************************************************************
Referenced pattern list written to: list/referenced.list
[INFO]       0.061[0.002]    || *** NEW FILE *** To save it:  cp list/referenced.list .ref/referenced.list
[INFO]       0.061[0.000]    || **********************************************************************

因此,从输出中我们可以看到创建了接口的两个实例,每个生成的顶级流一个实例,传递给Pattern.create的选项将传递到接口的初始化方法中。

请注意,当顶级流导入子流/组件时,不会实例化新接口。

最初,每次遇到Flow.create时都会创建一个新的接口实例,这与重新加载目标的时间相同。我们这样做是因为我们已经看到了早期实现中的问题,当时目标在整个流中保持不变。这导致一些流生成顺序依赖关系开始蔓延到某些应用程序中,例如,当您独立生成prb1.rb时,prb1.rb的输出与其他流同时生成时是不同的。 因此,通过每次都从头开始,它消除了根据目标之前所做的事情无意中更改流输出的可能性。

但最终,我们发现,在生成完整顶级流的上下文中,我们确实需要一些持久状态可用于跟踪测试数量计数之类的事情。因此,为了妥协,我们在每个Flow.create都保留了目标刷新,但仅在遇到新的顶级Flow.create时才刷新界面。

到目前为止,这在实践中运作良好。但是,如果您觉得需要一个为整个 Origen 程序生成命令保留的接口,那么也许您遇到了我们没有设想过的用例,或者也许还有另一种方法可以完成您想要实现的目标。

如果需要,请打开另一个问题以提供有关此的更多详细信息。

最新更新