On 19.11.2013 11:09, Johan De Wit wrote:
> Hi,
> 
> I should have payed much more attention in the programming lessons, or
> maybe it is because I took them too long ago ...
> 
> I'm trying to write a custom type, and I started with writing the rspec
> first, then the type definition, and somewhere in the future, i will
> have to write the providers.
> 
> I'm currently struggling with the following property : (it is openldap
> related)
> 
> I want to manage the configuration settings : 'olcAllow' witch contains
> a space separated list of keywords like "bind_v2 bind_anon_cred"
> 
> in the manifest it should say :
> 
> class myldap {
> 
> ldapconfig { 'config0':
>   allow => ['bind_v2', 'bind_anon_cred'],
>   ...
> }
> 
> In the rspec file, i defined :
> 
>     it "should accept property allow" do
>       @test = Puppet::Type.type(:ldapconfig).new(:name => 'config',
> property => ['bind_v2', 'bind_anon_cred'] )
>       @test[property].should == ['bind_v2', 'bind_anon_cred']
>     end
> 
> And in the type code :
> 
>   newproperty(:allows, :array_matching => :all) do
>     desc "Specify a set of features to be allowed."
>     newvalues(:bind_v2, :bind_anon_cred, :bind_anon_dn, :update_anon,
> :none)
>     defaultto(:none)
>     .....
>   end
> 
> 
> Running the unit test in this case will fail, because the array strings
> are converted to labels.
> 
> My question now, what is the proper way to solve this ?
> 
> a:  the rspec should test for the array with labels, and postpone
> conversion to the provider code.
> b. Already translate the value provided in the manifest to the final
> required output, in this case, the array will be converted to a sorted
> string of space separated allowed keyboards.

I'd go with a) here. If the list of possible values is not provider
specific but specific to the resource type, the `newvalues` function is
the way to go. And as you already noticed your type spec would then read
something like

    it "should allow bind_v2" do
      described_class.new(:name => 'config',:allow =>
'bind_v2')[:allow].should == [ :bind_v2 ]
    end

    it "should not allow foo" do
      expect { described_class.new(:name => 'config',:allow => 'foo')
}.to raise_error Puppet::Error, /some error message/
    end

So you would expect the value to turn into an array of symbols, even
though the user passed strings or an array of strings. This makes also
sense to test because you know what the provider will receive.

e.g. if you write a provider to receive the current value

    def allow
      # has to return the current value as an array of symbols
      # because you know the current value will be compared
      # against the should-value of the resource and that is always
      # an array of symbols (as shown in your tests)
    end

and set a new value

    def allow=(new_value)
      # because of your test above you already know that new_value
      # (the should-value) is always an array of symbols, eventhough the
      # user may have passed a single value, e.g. `allow => bind_v2`
    end

> I'm leaning towards b.  This gives the possibility to do more accurate
> value checking of the parameters, and error will be catched during
> catalog compilation.

b) will also lead to a compilation error if the user specifies an
invalid value. And if your provider has to transform the data (e.g. turn
the array of symbols into a space seperated list) you should test the
correct behaviour and write tests for your setter methods of your provider


> On the other hand, the provider could validate the
> values using in this case the installed ldap utilities for testing, and
> errors will generate a runtime error when executing the catalog on the
> client.  But i don't like the possibility to misconfigure, and break the
> ldap configuration by a puppet run.
> 
> I still have not a clue what should go in the provider code, and what
> should be handled by the type definition.  But it feels right to me too
> do all validation and data transformation.
> 
> Grts
> 
> johan
> 

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-dev/528E7849.6000807%40taunusstein.net.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to