1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2003-2020. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20
21%%----------------------------------------------------------------------
22%% Purpose: Test the snmp mib compiler
23%%
24%% Run test: ts:run(snmp, snmp_compiler_SUITE, [batch]).
25%%
26%%----------------------------------------------------------------------
27-module(snmp_compiler_SUITE).
28
29%%----------------------------------------------------------------------
30%% Include files
31%%----------------------------------------------------------------------
32-include_lib("common_test/include/ct.hrl").
33-include("snmp_test_lib.hrl").
34-include_lib("snmp/include/snmp_types.hrl").
35
36
37%%----------------------------------------------------------------------
38%% External exports
39%%----------------------------------------------------------------------
40-export([
41	 suite/0, all/0,
42         init_per_suite/1, end_per_suite/1,
43	 groups/0, init_per_group/2, end_per_group/2,
44         init_per_testcase/2, end_per_testcase/2,
45
46	 description/1,
47	 oid_conflicts/1,
48	 imports/1,
49	 module_identity/1,
50	 agent_capabilities/1,
51	 module_compliance/1,
52	 warnings_as_errors/1,
53	 augments_extra_info/1,
54
55	 otp_6150/1,
56	 otp_8574/1,
57	 otp_8595/1,
58	 otp_10799/1,
59	 otp_10808/1,
60	 otp_14145/1,
61         otp_13014/1,
62         otp_14196/1
63	]).
64
65
66%%======================================================================
67%% Common Test interface functions
68%%======================================================================
69
70suite() ->
71    [{ct_hooks, [ts_install_cth]}].
72
73
74all() ->
75    [
76     description,
77     oid_conflicts,
78     imports,
79     module_identity,
80     agent_capabilities,
81     module_compliance,
82     warnings_as_errors,
83     augments_extra_info,
84     {group, tickets}
85    ].
86
87groups() ->
88    [{tickets, [], tickets_cases()}].
89
90tickets_cases() ->
91    [
92     otp_6150,
93     otp_8574,
94     otp_8595,
95     otp_10799,
96     otp_10808,
97     otp_14145,
98     otp_13014,
99     otp_14196
100    ].
101
102
103%%
104%% -----
105%%
106
107init_per_suite(Config0) when is_list(Config0) ->
108
109    ?IPRINT("init_per_suite -> entry with"
110            "~n      Config: ~p"
111            "~n      Nodes:  ~p", [Config0, erlang:nodes()]),
112
113    case ?LIB:init_per_suite(Config0) of
114        {skip, _} = SKIP ->
115            SKIP;
116
117        Config1 when is_list(Config1) ->
118            Config2   = snmp_test_lib:init_suite_top_dir(?MODULE, Config1),
119            Config3   = snmp_test_lib:fix_data_dir(Config2),
120
121            %% Mib-dirs
122            %% data_dir is trashed by the test-server / common-test
123            %% so there is no point in fixing it...
124            MibDir    = snmp_test_lib:lookup(data_dir, Config3),
125            StdMibDir = filename:join([code:priv_dir(snmp), "mibs"]),
126
127            Config4 = [{mib_dir, MibDir}, {std_mib_dir, StdMibDir} | Config3],
128
129            %% We need a monitor on this node also
130            snmp_test_sys_monitor:start(),
131
132            snmp_test_mgr_counter_server:start(),
133
134            ?IPRINT("init_per_suite -> end when"
135                    "~n      Config: ~p", [Config4]),
136
137            Config4
138    end.
139
140
141end_per_suite(Config0) when is_list(Config0) ->
142    ?IPRINT("end_per_suite -> entry with"
143            "~n      Config0: ~p", [Config0]),
144
145    snmp_test_sys_monitor:stop(),
146    Config1 = ?LIB:end_per_suite(Config0),
147
148    ?IPRINT("end_per_suite -> end"),
149
150    Config1.
151
152
153%%
154%% -----
155%%
156
157init_per_group(_GroupName, Config) ->
158    Config.
159
160end_per_group(_GroupName, Config) ->
161    Config.
162
163
164
165%%
166%% -----
167%%
168
169init_per_testcase(Case, Config) when is_list(Config) ->
170
171    ?DBG("init_per_testcase -> entry with"
172	 "~n   Config: ~p", [Config]),
173
174    CaseTopDir = snmp_test_lib:init_testcase_top_dir(Case, Config),
175
176    [{case_top_dir, CaseTopDir} | Config].
177
178end_per_testcase(_Case, Config) when is_list(Config) ->
179    Config.
180
181
182
183%%======================================================================
184%% Test functions
185%%======================================================================
186
187description(suite) -> [];
188description(Config) when is_list(Config) ->
189    put(tname,desc),
190    ?IPRINT("starting with Config: "
191            "~n   ~p", [Config]),
192
193    Dir = ?config(case_top_dir, Config),
194    Filename   = join(Dir,"test"),
195    MibSrcName = Filename ++ ".mib",
196    MibBinName = Filename ++ ".bin",
197    Desctext   = "This is a test description",
198    Oid = [1,3,6,1,2,1,15,1],
199    write_mib(MibSrcName,Desctext),
200    ?line {ok,_} = snmpc:compile(MibSrcName, [{outdir,      Dir},
201					      {group_check, false},
202					      {warnings,    false},
203					      {description, false}]),
204    MIB1 = read_mib(MibBinName),
205    %% ?IPRINT("description -> MIB1: ~n~p~n", [MIB1]),
206    check_mib(MIB1#mib.mes, Oid,  undefined),
207    ?line {ok,_} = snmpc:compile(MibSrcName, [{outdir,      Dir},
208					      {group_check, false},
209					      {warnings,    false},
210					      {description, true}]),
211    MIB2 = read_mib(MibBinName),
212    %% ?IPRINT("description -> MIB2: ~n~p~n", [MIB2]),
213    check_mib(MIB2#mib.mes, Oid, Desctext),
214
215    %% Cleanup
216    file:delete(MibSrcName),
217    file:delete(MibBinName),
218    ok.
219
220
221%%======================================================================
222
223oid_conflicts(suite) -> [];
224oid_conflicts(Config) when is_list(Config) ->
225    put(tname,oid_conflicts),
226    ?IPRINT("starting with Config: "
227            "~n   ~p", [Config]),
228
229    Dir = ?config(case_top_dir, Config),
230    Mib = join(Dir,"TESTv2.mib"),
231    ?line ok = write_oid_conflict_mib(Mib),
232    ?line {error,compilation_failed} =
233	snmpc:compile(Mib,[{outdir, Dir},{verbosity,trace}]),
234    ok.
235
236
237%%======================================================================
238
239imports(suite) ->
240    [];
241imports(Config) when is_list(Config) ->
242    ?SKIP(not_yet_implemented).
243
244
245%%======================================================================
246
247module_identity(suite) ->
248    [];
249module_identity(Config) when is_list(Config) ->
250    ?SKIP(not_yet_implemented).
251
252
253%%======================================================================
254
255agent_capabilities(suite) ->
256    [];
257agent_capabilities(Config) when is_list(Config) ->
258    put(tname,agent_capabilities),
259    ?IPRINT("starting with Config: "
260            "~n   ~p", [Config]),
261
262    SnmpPrivDir    = which_priv_dir(snmp),
263    SnmpMibsDir    = join(SnmpPrivDir, "mibs"),
264    Dir   = ?config(mib_dir, Config),
265    AcMib = join(Dir,"AC-TEST-MIB.mib"),
266    ?line {ok, MibFile1} = snmpc:compile(AcMib, [options,
267						 version,
268						 {i,         [SnmpMibsDir]},
269						 {outdir,    Dir},
270						 {verbosity, trace}]),
271    ?line {ok, Mib1} = snmp_misc:read_mib(MibFile1),
272    ?line {ok, MibFile2} = snmpc:compile(AcMib, [options,
273						 version,
274						 agent_capabilities,
275						 {i,         [SnmpMibsDir]},
276						 {outdir,    Dir},
277						 {verbosity, trace}]),
278    ?line {ok, Mib2} = snmp_misc:read_mib(MibFile2),
279    MEDiff = Mib2#mib.mes -- Mib1#mib.mes,
280    %% This is a rather pathetic test, but it is somthing...
281    ?IPRINT("agent_capabilities -> "
282            "~n   MEDiff: ~p"
283            "~n   Mib1:   ~p"
284            "~n   Mib2:   ~p", [MEDiff, Mib1, Mib2]),
285    case length(MEDiff) of
286	2 ->
287	    ok;
288	_BadLen ->
289	    exit({unexpected_mes, MEDiff})
290    end,
291    ok.
292
293
294%%======================================================================
295
296module_compliance(suite) ->
297    [];
298module_compliance(Config) when is_list(Config) ->
299    put(tname, module_compliance),
300    ?IPRINT("starting with Config: "
301            "~n   ~p", [Config]),
302
303    SnmpPrivDir = which_priv_dir(snmp),
304    SnmpMibsDir = join(SnmpPrivDir, "mibs"),
305    Dir         = ?config(mib_dir, Config),
306    AcMib       = join(Dir,"MC-TEST-MIB.mib"),
307    ?line {ok, MibFile1} = snmpc:compile(AcMib, [options,
308						 version,
309						 {i,           [SnmpMibsDir]},
310						 {outdir,      Dir},
311						 {verbosity,   trace}]),
312    ?line {ok, Mib1} = snmp_misc:read_mib(MibFile1),
313    ?line {ok, MibFile2} = snmpc:compile(AcMib, [options,
314						 version,
315						 module_compliance,
316						 {i,           [SnmpMibsDir]},
317						 {outdir,      Dir},
318						 {verbosity,   trace}]),
319    ?line {ok, Mib2} = snmp_misc:read_mib(MibFile2),
320    MEDiff = Mib2#mib.mes -- Mib1#mib.mes,
321    %% This is a rather pathetic test, but it is somthing...
322    ?IPRINT("module_compliance -> "
323            "~n   MEDiff: ~p"
324            "~n   Mib1:   ~p"
325            "~n   Mib2:   ~p", [MEDiff, Mib1, Mib2]),
326    case length(MEDiff) of
327	1 ->
328	    ok;
329	_BadLen ->
330	    exit({unexpected_mes, MEDiff})
331    end,
332    ok.
333
334
335%%======================================================================
336
337warnings_as_errors(suite) ->
338    ["OTP-9437"];
339warnings_as_errors(Config) when is_list(Config) ->
340    put(tname,warnings_as_errors),
341    ?IPRINT("starting with Config: "
342            "~n   ~p", [Config]),
343    Dir     = ?config(case_top_dir, Config),
344    MibDir  = ?config(mib_dir,  Config),
345    MibFile = join(MibDir, "OTP8574-MIB.mib"),
346    OutFile = join(Dir, "OTP8574-MIB.bin"),
347    Opts =  [{group_check, false},
348	     {outdir,      Dir},
349	     {verbosity,   trace},
350	     relaxed_row_name_assign_check],
351    {error, compilation_failed} =
352	snmpc:compile(MibFile, [warnings_as_errors|Opts]),
353    false = filelib:is_regular(OutFile),
354    {ok, _} = snmpc:compile(MibFile, Opts),
355    true = filelib:is_regular(OutFile),
356    ok = file:delete(OutFile),
357    ok.
358
359
360%%======================================================================
361
362otp_6150(suite) ->
363    [];
364otp_6150(Config) when is_list(Config) ->
365    put(tname, otp6150),
366    ?IPRINT("starting with Config: "
367            "~n   ~p", [Config]),
368
369    Dir     = ?config(case_top_dir, Config),
370    MibDir  = ?config(mib_dir,  Config),
371    MibFile = join(MibDir, "ERICSSON-TOP-MIB.mib"),
372    ?line {ok, Mib} =
373	snmpc:compile(MibFile, [{outdir, Dir}, {verbosity, trace}]),
374    ?IPRINT("otp_6150 -> Mib: "
375            "~n   ~p", [Mib]),
376    ok.
377
378
379%%======================================================================
380
381otp_8574(suite) ->
382    [];
383otp_8574(Config) when is_list(Config) ->
384    put(tname, otp8574),
385    ?IPRINT("starting with Config: "
386            "~n   ~p", [Config]),
387
388    Dir     = ?config(case_top_dir, Config),
389    MibDir  = ?config(mib_dir,  Config),
390    MibFile = join(MibDir, "OTP8574-MIB.mib"),
391
392    ?IPRINT("ensure compile fail without relaxed assign check"),
393    case snmpc:compile(MibFile, [{group_check, false}, {outdir, Dir}]) of
394	{error, compilation_failed} ->
395	    ?IPRINT("with relaxed assign check MIB compiles with warning"),
396	    case snmpc:compile(MibFile, [{group_check, false},
397					 {outdir, Dir},
398					 relaxed_row_name_assign_check]) of
399		{ok, _Mib} ->
400		    ok;
401		{error, Reason} ->
402		    ?EPRINT("unexpected compile failure: "
403                            "~n   Reason: ~p", [Reason]),
404		    exit({unexpected_compile_failure, Reason})
405	    end;
406
407	{ok, _} ->
408	    ?EPRINT("unexpected compile success"),
409	    exit(unexpected_compile_success)
410    end.
411
412
413%%======================================================================
414
415otp_8595(suite) ->
416    [];
417otp_8595(Config) when is_list(Config) ->
418    put(tname, otp8595),
419    ?IPRINT("starting with Config: "
420            "~n   ~p", [Config]),
421
422    Dir     = ?config(case_top_dir, Config),
423    MibDir  = ?config(mib_dir,  Config),
424    MibFile = join(MibDir, "OTP8595-MIB.mib"),
425    ?line {ok, Mib} =
426	snmpc:compile(MibFile, [{outdir,      Dir},
427				{verbosity,   trace},
428				{group_check, false}]),
429    ?IPRINT("Mib: ~n~p~n", [Mib]),
430    ok.
431
432
433%%======================================================================
434
435otp_10799(suite) ->
436    [];
437otp_10799(Config) when is_list(Config) ->
438    put(tname, otp10799),
439    ?IPRINT("starting with Config: "
440            "~n   ~p", [Config]),
441
442    Dir     = ?config(case_top_dir, Config),
443    MibDir  = ?config(mib_dir,      Config),
444    MibFile = join(MibDir, "OTP10799-MIB.mib"),
445    ?line {ok, Mib} =
446	snmpc:compile(MibFile, [{outdir, Dir}, {verbosity, trace}]),
447    ?IPRINT("Mib: "
448            "~n   ~p", [Mib]),
449    ok.
450
451
452%%======================================================================
453
454otp_10808(suite) ->
455    [];
456otp_10808(Config) when is_list(Config) ->
457    put(tname, otp10808),
458    ?IPRINT("starting with Config: "
459            "~n   ~p", [Config]),
460
461    Dir     = ?config(case_top_dir, Config),
462    MibDir  = ?config(mib_dir,      Config),
463    MibFile = join(MibDir, "OTP10808-MIB.mib"),
464    ?line {ok, Mib} =
465	snmpc:compile(MibFile, [{outdir,      Dir},
466				{verbosity,   trace},
467				{group_check, false}]),
468    ?IPRINT("Mib: "
469            "~n   ~p", [Mib]),
470    ok.
471
472
473%%======================================================================
474
475otp_14145(suite) ->
476    [];
477otp_14145(Config) when is_list(Config) ->
478    put(tname, otp14145),
479    ?IPRINT("starting with Config: "
480            "~n   ~p", [Config]),
481
482    Dir     = ?config(case_top_dir, Config),
483    MibDir  = ?config(mib_dir,      Config),
484    MibName = "OTP14145-MIB",
485    MibFile = join(MibDir, MibName++".mib"),
486    ?line {ok, MibBin} =
487	snmpc:compile(MibFile, [{outdir, Dir},
488				{verbosity, trace},
489				{group_check, false},
490				module_compliance]),
491    ?IPRINT("Mib: "
492            "~n   ~p", [MibBin]),
493    MIB = read_mib(MibBin),
494    Oid = [1,3,6,1,2,1,67,4],
495    check_mib(MIB#mib.mes, Oid, undefined),
496    ok.
497
498
499%%======================================================================
500
501otp_13014(suite) ->
502    [];
503otp_13014(Config) when is_list(Config) ->
504    put(tname, otp13014),
505    ?IPRINT("starting with Config: "
506            "~n   ~p", [Config]),
507
508    Dir     = ?config(case_top_dir, Config),
509    MibDir  = ?config(mib_dir,      Config),
510    MibName = "Test-LLDP-MIB",
511    MibFile = join(MibDir, MibName++".mib"),
512    ?line {ok, MibBin} =
513	snmpc:compile(MibFile, [{outdir, Dir},
514				{verbosity, log},
515				{group_check, false},
516				module_compliance]),
517    ?IPRINT("Mib: "
518            "~n   ~p", [MibBin]),
519    #mib{mes = MEs} = read_mib(MibBin),
520    Oid = [1,0,8802,1,1,2,1,1,7],
521    #me{
522       entrytype = table,
523       aliasname = lldpConfigManAddrTable,
524       assocList = [{table_info,TableInfo}]} =
525        lists:keyfind(Oid, #me.oid, MEs),
526    #table_info{
527       nbr_of_cols = 1,
528       first_accessible = 1,
529       not_accessible = [],
530       index_types = {augments,{lldpLocManAddrEntry,undefined}}} =
531        TableInfo,
532    ok.
533
534
535%%======================================================================
536
537otp_14196(suite) ->
538    [];
539otp_14196(Config) when is_list(Config) ->
540    put(tname, otp14196),
541    ?IPRINT("starting with Config: "
542            "~n   ~p", [Config]),
543
544    Dir     = ?config(case_top_dir, Config),
545    MibDir  = ?config(mib_dir,      Config),
546    MibFile = join(MibDir, "OTP14196-MIB.mib"),
547    ?line {ok, Mib} =
548	snmpc:compile(MibFile, [{outdir, Dir}, {verbosity, trace}]),
549    ?IPRINT("Mib: "
550            "~n   ~p", [Mib]),
551    ok.
552
553
554%%======================================================================
555
556augments_extra_info(suite) ->
557    [];
558augments_extra_info(Config) when is_list(Config) ->
559    put(tname, augments_extra_info),
560    ?IPRINT("starting with Config: "
561            "~n   ~p", [Config]),
562
563    Dir       = ?config(case_top_dir, Config),
564    MibDir    = ?config(mib_dir,      Config),
565    Test2File = join(MibDir, "Test2.mib"),
566    Test3File = join(MibDir, "Test3.mib"),
567    ?line {ok, Test2BinFile} =
568	snmpc:compile(Test2File, [{outdir,      Dir},
569				  {verbosity,   silence},
570				  {group_check, false}]),
571    ?IPRINT("Test2BinFile: "
572            "~n   ~p", [Test2BinFile]),
573    ?line {ok, Test3BinFile} =
574	snmpc:compile(Test3File, [{i,           [MibDir]},
575				  {outdir,      Dir},
576				  {verbosity,   silence},
577				  {group_check, true}]),
578    ?IPRINT("Test3BinFile: "
579            "~n   ~p", [Test3BinFile]),
580    {ok, Test3Mib} = snmp_misc:read_mib(Test3BinFile),
581    ?IPRINT("Test3Mib: "
582            "~n   ~p", [Test3Mib]),
583    %% There is only one table in this mib
584    #mib{table_infos = [{TableName, TI}]} = Test3Mib,
585    ?IPRINT("TableName: ~p"
586            "~n   Table Info: ~p", [TableName, TI]),
587    #table_info{nbr_of_cols      = 4,
588		defvals          = DefVals,
589		not_accessible   = [2,4],
590		index_types      = {augments, {tEntry, undefined}},
591		first_accessible = 1} = TI,
592    ?IPRINT("Table info:   ~p"
593            "~n   DefVals: ~p"
594            "~n", [TableName, DefVals]),
595    ok.
596
597
598%%======================================================================
599%% Internal functions
600%%======================================================================
601
602write_oid_conflict_mib(Filename) ->
603    MibText = "TESTv2 DEFINITIONS ::= BEGIN
604
605IMPORTS
606	MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE,
607    Integer32, snmpModules ,experimental
608        FROM SNMPv2-SMI
609	MODULE-COMPLIANCE, OBJECT-GROUP, NOTIFICATION-GROUP
610        FROM SNMPv2-CONF
611	DisplayString
612        FROM SNMPv2-TC
613	RowStatus
614        FROM STANDARD-MIB;
615
616
617exampleModule MODULE-IDENTITY
618LAST-UPDATED \"0005290000Z\"
619        ORGANIZATION \"Erlang\"
620        CONTACT-INFO \" test mib
621                        Ericsson Utvecklings AB
622Open System
623Box 1505
624SE-125 25 ÄLVSJÖ\"
625
626DESCRIPTION
627\" Objects for management \"
628        REVISION   \"0005290000Z\"
629        DESCRIPTION
630\"The initial version\"
631        ::= { snmpModules 1 }
632
633example1 OBJECT IDENTIFIER ::= { experimental 7}
634-- example2 OBJECT IDENTIFIER ::= { experimental 7}
635
636
637myName OBJECT-TYPE
638SYNTAX      DisplayString
639MAX-ACCESS  read-write
640STATUS  current
641DESCRIPTION
642\"My own name\"
643              ::= { example1 1 }
644
645myNotification NOTIFICATION-TYPE
646STATUS      current
647DESCRIPTION
648\"test trap.\"
649              ::= { example1 1 }
650
651friendsTable OBJECT-TYPE
652SYNTAX  SEQUENCE OF FriendsEntry
653MAX-ACCESS  not-accessible
654STATUS   current
655DESCRIPTION
656\"A list of friends.\"
657              ::= { example1 4 }
658
659friendsEntry OBJECT-TYPE
660SYNTAX  FriendsEntry
661MAX-ACCESS  not-accessible
662STATUS  current
663DESCRIPTION
664\"\"
665              INDEX   { fIndex }
666::= { friendsTable 1 }
667
668FriendsEntry ::= SEQUENCE {
669		   fIndex   INTEGER,
670		   fName    DisplayString,
671		   fAddress DisplayString,
672		   fStatus  RowStatus
673		  }
674
675fIndex OBJECT-TYPE
676SYNTAX      INTEGER
677MAX-ACCESS  read-only
678STATUS      current
679DESCRIPTION
680\"number of friend\"
681              ::= { friendsEntry 1 }
682
683fName OBJECT-TYPE
684SYNTAX      DisplayString (SIZE (0..255))
685MAX-ACCESS  read-write
686STATUS      current
687DESCRIPTION
688\"Name of  a friend\"
689              ::= { friendsEntry 2 }
690
691fAddress OBJECT-TYPE
692SYNTAX      DisplayString (SIZE (0..255))
693MAX-ACCESS  read-write
694STATUS      current
695DESCRIPTION
696\"Address of a friend\"
697              ::= { friendsEntry 3 }
698
699fStatus OBJECT-TYPE
700SYNTAX      RowStatus
701MAX-ACCESS  read-write
702STATUS      current
703DESCRIPTION
704\"The status of this conceptual row.\"
705              ::= { friendsEntry 4 }
706
707-- myName2 OBJECT IDENTIFIER ::= { example1 1 }
708
709friendGroup OBJECT-GROUP
710OBJECTS { myName, fIndex, fName,fAddress, fStatus }
711STATUS current
712DESCRIPTION \" A object group\"
713        ::= { example1 2 }
714
715myNotificationGroup NOTIFICATION-GROUP
716NOTIFICATIONS { myNotification }
717STATUS     current
718DESCRIPTION
719\"Test notification group\"
720      ::= { example1 3 }
721END",
722
723    file:write_file(Filename, MibText).
724
725
726write_mib(Filename,Desc) ->
727    Binary = "Test DEFINITIONS ::= BEGIN
728
729IMPORTS
730	MODULE-IDENTITY, OBJECT-TYPE,
731    snmpModules, mib-2
732        FROM SNMPv2-SMI ;
733
734snmpMIB MODULE-IDENTITY
735LAST-UPDATED \"9511090000Z\"
736    ORGANIZATION \"\"
737    CONTACT-INFO \"\"
738    DESCRIPTION
739::= { snmpModules 1 }
740
741
742test   OBJECT IDENTIFIER ::= { mib-2 15 }
743
744bits1 OBJECT-TYPE
745SYNTAX      BITS { b0(0), b1(1), b2(2) }
746MAX-ACCESS  read-write
747STATUS      current
748DESCRIPTION	\"" ++ Desc ++ "\"
749    ::= { test 1 }
750
751END",
752    Message = file:write_file(Filename, Binary),
753case Message of
754    ok -> ok;
755    {error, Reason} ->
756	exit({failed_writing_mib, Reason})
757end.
758
759
760read_mib(Filename) ->
761    case file:read_file(Filename) of
762        {ok,Bin} ->
763	    binary_to_term(Bin);
764        {error,Reason} ->
765            exit({failed_reading_mib,Filename,Reason})
766    end.
767
768check_mib([],_,_) ->
769    not_found;
770check_mib([#me{oid = Oid, description = Description}| _T], Oid, Testdata) ->
771    check_desc(Description, Testdata);
772check_mib([_H|T], Oid, Testdata ) ->
773    check_mib(T, Oid, Testdata ).
774
775check_desc(Desc, Desc) ->
776    ok;
777check_desc(Desc1, Desc2) ->
778    exit({'description not equal', Desc1, Desc2}).
779
780
781which_priv_dir(App) ->
782    case code:priv_dir(App) of
783        Dir when is_list(Dir) ->
784            Dir;
785        {error, Reason} ->
786            exit({App, priv_dir_not_found, Reason})
787    end.
788
789
790%% join(Comp) ->
791%%     filename:join(Comp).
792
793join(A,B) ->
794    filename:join(A,B).
795
796