summaryrefslogtreecommitdiff
path: root/ACE/bin/PerlACE/TestTarget_LVRT.pm
blob: 3e5df034e449df7566c81a59406bb64b4620c348 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
#! /usr/bin/perl
# $Id$
#
# TestTarget_LVRT - how to manage the test environment on a LabVIEW RT target.
#
# We can FTP files to and from the LabVIEW target, but there's no NFS or
# SMB shares.
# Most information about the target itself is specified via environment
# variables. Environment variables with settings are named using the target's
# config name with a specific suffix. The current environment variables are:
#   <config-name>_IPNAME - the host name/IP of the target.
#   <config-name>_CTLPORT- the TCP port number to connect to for the test
#                          controller. If this is not set, port 8888 is used.
#   <config-name>_FSROOT - the root of the filesystem on the target where
#                          ACE files will be created from (cwd, if you will).
#                          If this is not set, "\ni-rt" is used as the root.
#
# Each of these settings are stored in a member variable of the same name in
# each object. The process objects can access them using, e.g.,
# $self->{TARGET}->{IPNAME}.
#
# This class also makes an FTP object available to process objects that are
# created. FTP is set up before creating a process object and can be used to
# transfer files to and from the LVRT target.

package PerlACE::TestTarget_LVRT;
our @ISA = "PerlACE::TestTarget";

### Constructor and Destructor

sub new
{
    my $proto = shift;
    my $config_name = shift;
    my $class = ref ($proto) || $proto;
    my $self = {};
    bless ($self, $class);
    $self->GetConfigSettings($config_name);
    my $targethost;
    my $env_name = $config_name.'_IPNAME';
    if (exists $ENV{$env_name}) {
        $targethost = $ENV{$env_name};
    }
    else {
        print STDERR "You must define target hostname/IP with $env_name\n";
        undef $self;
        return undef;
    }

    $env_name = $config_name.'_CTLPORT';
    if (exists $ENV{$env_name}) {
        $self->{CTLPORT} = $ENV{$env_name};
    }
    else {
        print STDERR "Warning: no $env_name variable; falling back to ",
                     "port 8888\n";
        $self->{CTLPORT} = 8888;
    }

    $env_name = $config_name.'_FSROOT';
    my $fsroot = '\\ni-rt\\system';
    if (exists $ENV{$env_name}) {
        $fsroot = $ENV{$env_name};
    }
    else {
        print STDERR "Warning: no $env_name variable; falling back ",
                     "to $fsroot\n";
    }
    $self->{FSROOT} = $fsroot;

    $self->{REBOOT_CMD} = $ENV{"ACE_REBOOT_LVRT_CMD"};
    if (!defined $self->{REBOOT_CMD}) {
        $self->{REBOOT_CMD} = 'I_Need_A_Reboot_Command';
    }
    $self->{REBOOT_TIME} = $ENV{"ACE_LVRT_REBOOT_TIME"};
    if (!defined $self->{REBOOT_TIME}) {
        $self->{REBOOT_TIME} = 200;
    }

    $self->{REBOOT_TIME} = $ENV{"ACE_RUN_LVRT_REBOOT_TIME"};
    if (!defined $self->{REBOOT_TIME}) {
        $self->{REBOOT_TIME} = 200;
    }
    $self->{REBOOT_NEEDED} = undef;

    $self->{FTP} = new Net::FTP ($targethost);
    $self->{IPNAME} = $targethost;
    if (!defined $self->{FTP}) {
        print STDERR "Error opening FTP to $targethost: $@\n";
        $self->{REBOOT_NEEDED} = 1;
        undef $self;
        return undef;
    }
    $self->{FTP}->login("","");

    return $self;
}

sub DESTROY
{
    my $self = shift;

    # Reboot if needed; set up clean for the next test.
    if (defined $self->{REBOOT_NEEDED} && $self->{REBOOT_CMD}) {
        $self->RebootNow;
    }

    # See if there's a log; should be able to retrieve it from rebooted target.
    if (defined $ENV{'ACE_TEST_VERBOSE'}) {
      print STDERR "LVRT target checking for remaining log...\n";
    }
    $self->GetStderrLog();
    if (defined $self->{FTP}) {
        $self->{FTP}->close;
        $self->{FTP} = undef;
    }
}

##################################################################

sub LocalFile ($)
{
    my $self = shift;
    my $file = shift;
    my $newfile = $self->{FSROOT} . '\\' . $file;
    print STDERR "LVRT LocalFile for $file is $newfile\n";
    return $newfile;
}

sub DeleteFile ($)
{
    my $self = shift;
    $self->{FTP}->login("","");
    foreach my $file (@_) {
      my $newfile = $self->LocalFile($file);
      $self->{FTP}->delete($newfile);
    }
}

sub GetFile ($)
{
    # Use FTP to retrieve the file from the target; should still be open.
    my $self = shift;
    my $remote_file = shift;
    my $local_file = shift;
    my $newfile = $self->LocalFile($file);
    $self->{FTP}->ascii();
    if ($self->{FTP}->get($newfile, $local_file)) {
        return 0;
    }
    return -1;
}

sub WaitForFileTimed ($)
{
    my $self = shift;
    my $file = shift;
    my $timeout = shift;
    my $newfile = $self->LocalFile($file);
    my $targetport = $self->{CTLPORT};
    my $target = new Net::Telnet(Errmode => 'return');
    if (!$target->open(Host => $self->{IPNAME}, Port => $targetport)) {
        print STDERR "ERROR: target $self->{IPNAME}:$targetport: ",
                      $target->errmsg(), "\n";
        return -1;
    }
    my $cmdline = "waitforfile $newfile $timeout";
    if (defined $ENV{'ACE_TEST_VERBOSE'}) {
      print "-> $cmdline\n";
    }
    $target->print("$cmdline");
    my $reply;
    # Add a small comms delay factor to the timeout
    $timeout = $timeout + 2;
    $reply = $target->getline(Timeout => $timeout);
    if (defined $ENV{'ACE_TEST_VERBOSE'}) {
      print "<- $reply\n";
    }
    $target->close();
    if ($reply eq "OK\n") {
        return 0;
    }
    return -1;
}

sub CreateProcess ($)
{
    my $self = shift;
    my $process = new PerlACE::ProcessLVRT ($self, @_);
    return $process;
}

sub GetStderrLog ($)
{
    my $self = shift;
    # Tell the target to snapshot the stderr log; if there is one, copy
    # it up here and put it out to our stderr.
    my $targetport = $self->{CTLPORT};
    my $target = new Net::Telnet(Errmode => 'return');
    if (!$target->open(Host => $self->{IPNAME}, Port => $targetport)) {
        print STDERR "ERROR: target $self->{IPNAME}:$targetport: ",
                      $target->errmsg(), "\n";
        return;
    }
    my $cmdline = "snaplog";
    if (defined $ENV{'ACE_TEST_VERBOSE'}) {
        print "-> $cmdline\n";
    }
    $target->print("$cmdline");
    my $reply;
    $reply = $target->getline();
    if (defined $ENV{'ACE_TEST_VERBOSE'}) {
        print "<- $reply\n";
    }
    $target->close();
    if ($reply eq "NONE\n") {
        return;
    }
    chomp $reply;
    if (undef $self->{FTP}) {
        $self->{FTP} = new Net::FTP ($self->{IPNAME});
        if (!defined $self->{FTP}) {
            print STDERR "$@\n";
            return -1;
        }
        $self->{FTP}->login("","");
    }
    $self->{FTP}->ascii();
    if ($self->{FTP}->get($reply, "stderr.txt")) {
        $self->{FTP}->delete($reply);
        open(LOG, "stderr.txt");
        while (<LOG>) {
            print STDERR;
        }
        close LOG;
        unlink "stderr.txt";
    }
    return;
}

# Copy a file to the target. Adjust for different types (DLL, EXE, TEXT)
# and debug/non (for DLLs). Additionally, a file can be removed when this
# object is deleted, or left in place.
sub NeedFile ($)
{
    my $self = shift;
}

# Need a reboot when this target is destroyed.
sub NeedReboot ($)
{
    my $self = shift;
    $self->{REBOOT_NEEDED} = 1;
}

# Reboot target
sub RebootNow ($)
{
    my $self = shift;
    $self->{REBOOT_NEEDED} = undef;
    print STDERR "Attempting to reboot target...\n";
    if (defined $self->{FTP}) {
        $self->{FTP}->close;
        $self->{FTP} = undef;
    }
    system ($self->{REBOOT_CMD});
    sleep ($self->{REBOOT_TIME});
}

# Reboot now then try to restore the FTP connection.
sub RebootReset ($)
{
    my $self = shift;
    $self->RebootNow;
    my $targethost = $self->{IPNAME};
    $self->{FTP} = new Net::FTP ($targethost);
    if (!defined $self->{FTP}) {
        print STDERR "Error reestablishing FTP to $targethost: $@\n";
    }
    else {
        $self->{FTP}->login("","");
    }
}

1;